diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c9f93cff50f..3501c88b95f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22447,7 +22447,7 @@ namespace ts { // on empty arrays are possible without implicit any errors and new element types can be inferred without // type mismatch errors. const resultType = getObjectFlags(evolvedType) & ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType); - if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { + if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && !(resultType.flags & TypeFlags.Never) && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { return declaredType; } return resultType; diff --git a/tests/baselines/reference/exhaustiveSwitchStatements1.errors.txt b/tests/baselines/reference/exhaustiveSwitchStatements1.errors.txt index a8e02b04aa8..1f1bc0eca31 100644 --- a/tests/baselines/reference/exhaustiveSwitchStatements1.errors.txt +++ b/tests/baselines/reference/exhaustiveSwitchStatements1.errors.txt @@ -1,8 +1,9 @@ tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts(7,9): error TS7027: Unreachable code detected. tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts(235,5): error TS2367: This condition will always return 'false' since the types 'keyof O' and '"c"' have no overlap. +tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts(247,10): error TS2339: Property 'kind' does not exist on type 'never'. -==== tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts (2 errors) ==== +==== tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts (3 errors) ==== function f1(x: 1 | 2): string { if (!!true) { switch (x) { @@ -244,4 +245,17 @@ tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts(235,5): error !!! error TS2367: This condition will always return 'false' since the types 'keyof O' and '"c"' have no overlap. return o[k]; } - \ No newline at end of file + + // Repro from #35431 + type A = { kind: "abc" } | { kind: "def" }; + + function f35431(a: A) { + switch (a.kind) { + case "abc": + case "def": return; + default: + a!.kind; // Error expected + ~~~~ +!!! error TS2339: Property 'kind' does not exist on type 'never'. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/exhaustiveSwitchStatements1.js b/tests/baselines/reference/exhaustiveSwitchStatements1.js index d172b00b847..625265466a4 100644 --- a/tests/baselines/reference/exhaustiveSwitchStatements1.js +++ b/tests/baselines/reference/exhaustiveSwitchStatements1.js @@ -236,7 +236,18 @@ function ff(o: O, k: K) { k === 'c'; // Error return o[k]; } - + +// Repro from #35431 +type A = { kind: "abc" } | { kind: "def" }; + +function f35431(a: A) { + switch (a.kind) { + case "abc": + case "def": return; + default: + a!.kind; // Error expected + } +} //// [exhaustiveSwitchStatements1.js] "use strict"; @@ -453,6 +464,14 @@ function ff(o, k) { k === 'c'; // Error return o[k]; } +function f35431(a) { + switch (a.kind) { + case "abc": + case "def": return; + default: + a.kind; // Error expected + } +} //// [exhaustiveSwitchStatements1.d.ts] @@ -524,3 +543,9 @@ declare type O = { }; declare type K = keyof O | 'c'; declare function ff(o: O, k: K): number; +declare type A = { + kind: "abc"; +} | { + kind: "def"; +}; +declare function f35431(a: A): void; diff --git a/tests/baselines/reference/exhaustiveSwitchStatements1.symbols b/tests/baselines/reference/exhaustiveSwitchStatements1.symbols index 6ee1e4a9889..a9c2d820f2b 100644 --- a/tests/baselines/reference/exhaustiveSwitchStatements1.symbols +++ b/tests/baselines/reference/exhaustiveSwitchStatements1.symbols @@ -603,3 +603,26 @@ function ff(o: O, k: K) { >k : Symbol(k, Decl(exhaustiveSwitchStatements1.ts, 229, 17)) } +// Repro from #35431 +type A = { kind: "abc" } | { kind: "def" }; +>A : Symbol(A, Decl(exhaustiveSwitchStatements1.ts, 236, 1)) +>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 239, 10)) +>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 239, 28)) + +function f35431(a: A) { +>f35431 : Symbol(f35431, Decl(exhaustiveSwitchStatements1.ts, 239, 43)) +>a : Symbol(a, Decl(exhaustiveSwitchStatements1.ts, 241, 16)) +>A : Symbol(A, Decl(exhaustiveSwitchStatements1.ts, 236, 1)) + + switch (a.kind) { +>a.kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 239, 10), Decl(exhaustiveSwitchStatements1.ts, 239, 28)) +>a : Symbol(a, Decl(exhaustiveSwitchStatements1.ts, 241, 16)) +>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 239, 10), Decl(exhaustiveSwitchStatements1.ts, 239, 28)) + + case "abc": + case "def": return; + default: + a!.kind; // Error expected +>a : Symbol(a, Decl(exhaustiveSwitchStatements1.ts, 241, 16)) + } +} diff --git a/tests/baselines/reference/exhaustiveSwitchStatements1.types b/tests/baselines/reference/exhaustiveSwitchStatements1.types index 043bb099f01..4944989ed1d 100644 --- a/tests/baselines/reference/exhaustiveSwitchStatements1.types +++ b/tests/baselines/reference/exhaustiveSwitchStatements1.types @@ -704,3 +704,32 @@ function ff(o: O, k: K) { >k : keyof O } +// Repro from #35431 +type A = { kind: "abc" } | { kind: "def" }; +>A : A +>kind : "abc" +>kind : "def" + +function f35431(a: A) { +>f35431 : (a: A) => void +>a : A + + switch (a.kind) { +>a.kind : "abc" | "def" +>a : A +>kind : "abc" | "def" + + case "abc": +>"abc" : "abc" + + case "def": return; +>"def" : "def" + + default: + a!.kind; // Error expected +>a!.kind : any +>a! : never +>a : never +>kind : any + } +} diff --git a/tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts b/tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts index 9c03f039a8b..2bba269b89d 100644 --- a/tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts +++ b/tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts @@ -239,3 +239,15 @@ function ff(o: O, k: K) { k === 'c'; // Error return o[k]; } + +// Repro from #35431 +type A = { kind: "abc" } | { kind: "def" }; + +function f35431(a: A) { + switch (a.kind) { + case "abc": + case "def": return; + default: + a!.kind; // Error expected + } +} \ No newline at end of file