Skip to content

switch on enum exhaustive for direct return but not for indirect return #13241

Closed
@rogierschouten

Description

@rogierschouten

TypeScript Version: 2.1.4

Code

enum MyEnum {
	A,
	B
}

function thisGivesError(e: MyEnum): string {
	let s: string;
	switch (e) {
		case MyEnum.A: s = "it was A"; break;
		case MyEnum.B: s = "it was B"; break;
	}
	return s; // Variable 's' is used before being assigned
}

function good1(e: MyEnum): string {
	let s: string;
	switch (e) {
		case MyEnum.A: s = "it was A"; break;
		case MyEnum.B: s = "it was B"; break;
		default: s = "it was something else"; break;
	}
	return s; // ok
}

function good2(e: MyEnum): string {
	switch (e) {
		case MyEnum.A: return "it was A";
		case MyEnum.B: return "it was B";
	}
}

tsconfig.json:

{
	"compilerOptions": {
		"alwaysStrict": true,
		"declaration": true,
		"forceConsistentCasingInFileNames": false,
		"inlineSourceMap": true,
		"inlineSources": true,
		"module": "commonjs",
		"noFallthroughCasesInSwitch": true,
		"noImplicitAny": true,
		"noImplicitReturns": true,
		"noImplicitThis": true,
		"noLib": false,
		"noUnusedLocals": true,
		"noUnusedParameters": true,
		"outDir": "./dist",
		"preserveConstEnums": true,
		"pretty": true,
		"removeComments": false,
		"strictNullChecks": true,
		"suppressImplicitAnyIndexErrors": true,
		"target": "es5"
	},
}

Expected behavior:

Compiles

Actual behavior:

In the first function, returns 'Variable s is used before being assigned'. On the one hand, the compiler knows that the switch statment is exhaustive (see both functions below) and on the other hand it doesn't know that therefore the variable is assigned.

Might be related to #12771

Metadata

Metadata

Assignees

Labels

Design LimitationConstraints of the existing architecture prevent this from being fixed

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions