mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-11 09:24:19 -06:00
Fixed issue where non null assertion caused getFlowTypeOfReference to return the declared type if the type was already narrowed to never. (#35863)
This was caused by the fact that getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull) will return never both if resultType was already never and if resultType does not contain undefined or null. In the latter case returning the declaring type is correct, in the former case this causes something narrowed to never to still be typed as the original declared type.
This commit is contained in:
parent
3d6650eb4f
commit
71661b932a
@ -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;
|
||||
|
||||
@ -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];
|
||||
}
|
||||
|
||||
|
||||
// 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'.
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user