Fixed an issue with missingType narrowing by case undefined in default cases (#58001)

This commit is contained in:
Mateusz Burzyński 2024-05-01 17:57:42 +02:00 committed by GitHub
parent 33b156147b
commit f01cae8893
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 837 additions and 1 deletions

View File

@ -28543,7 +28543,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (!hasDefaultClause) {
return caseType;
}
const defaultType = filterType(type, t => !(isUnitLikeType(t) && contains(switchTypes, getRegularTypeOfLiteralType(extractUnitType(t)))));
const defaultType = filterType(type, t => !(isUnitLikeType(t) && contains(switchTypes, t.flags & TypeFlags.Undefined ? undefinedType : getRegularTypeOfLiteralType(extractUnitType(t)))));
return caseType.flags & TypeFlags.Never ? defaultType : getUnionType([caseType, defaultType]);
}

View File

@ -0,0 +1,75 @@
//// [tests/cases/compiler/narrowBySwitchDiscriminantUndefinedCase1.ts] ////
=== narrowBySwitchDiscriminantUndefinedCase1.ts ===
// https://github.com/microsoft/TypeScript/issues/57999
interface A {
>A : Symbol(A, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 0, 0))
optionalProp?: "hello";
>optionalProp : Symbol(A.optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 2, 13))
}
function func(arg: A) {
>func : Symbol(func, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 4, 1))
>arg : Symbol(arg, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 6, 14))
>A : Symbol(A, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 0, 0))
const { optionalProp } = arg;
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 7, 9))
>arg : Symbol(arg, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 6, 14))
switch (optionalProp) {
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 7, 9))
case undefined:
>undefined : Symbol(undefined)
return undefined;
>undefined : Symbol(undefined)
case "hello":
return "hello";
default:
assertUnreachable(optionalProp);
>assertUnreachable : Symbol(assertUnreachable, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 30, 1))
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 7, 9))
}
}
function func2() {
>func2 : Symbol(func2, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 17, 1))
const optionalProp = ["hello" as const][Math.random()];
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 20, 7))
>const : Symbol(const)
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
switch (optionalProp) {
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 20, 7))
case undefined:
>undefined : Symbol(undefined)
return undefined;
>undefined : Symbol(undefined)
case "hello":
return "hello";
default:
assertUnreachable(optionalProp);
>assertUnreachable : Symbol(assertUnreachable, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 30, 1))
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 20, 7))
}
}
function assertUnreachable(_: never): never {
>assertUnreachable : Symbol(assertUnreachable, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 30, 1))
>_ : Symbol(_, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 32, 27))
throw new Error("Unreachable path taken");
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
}

View File

@ -0,0 +1,124 @@
//// [tests/cases/compiler/narrowBySwitchDiscriminantUndefinedCase1.ts] ////
=== narrowBySwitchDiscriminantUndefinedCase1.ts ===
// https://github.com/microsoft/TypeScript/issues/57999
interface A {
optionalProp?: "hello";
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
}
function func(arg: A) {
>func : (arg: A) => "hello" | undefined
> : ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
>arg : A
> : ^
const { optionalProp } = arg;
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
>arg : A
> : ^
switch (optionalProp) {
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
case undefined:
>undefined : undefined
> : ^^^^^^^^^
return undefined;
>undefined : undefined
> : ^^^^^^^^^
case "hello":
>"hello" : "hello"
> : ^^^^^^^
return "hello";
>"hello" : "hello"
> : ^^^^^^^
default:
assertUnreachable(optionalProp);
>assertUnreachable(optionalProp) : never
> : ^^^^^
>assertUnreachable : (_: never) => never
> : ^^^^^^^^^^^^^^^^^^^
>optionalProp : never
> : ^^^^^
}
}
function func2() {
>func2 : () => "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
const optionalProp = ["hello" as const][Math.random()];
>optionalProp : "hello"
> : ^^^^^^^
>["hello" as const][Math.random()] : "hello"
> : ^^^^^^^
>["hello" as const] : "hello"[]
> : ^^^^^^^^^
>"hello" as const : "hello"
> : ^^^^^^^
>"hello" : "hello"
> : ^^^^^^^
>Math.random() : number
> : ^^^^^^
>Math.random : () => number
> : ^^^^^^^^^^^^
>Math : Math
> : ^^^^
>random : () => number
> : ^^^^^^^^^^^^
switch (optionalProp) {
>optionalProp : "hello"
> : ^^^^^^^
case undefined:
>undefined : undefined
> : ^^^^^^^^^
return undefined;
>undefined : undefined
> : ^^^^^^^^^
case "hello":
>"hello" : "hello"
> : ^^^^^^^
return "hello";
>"hello" : "hello"
> : ^^^^^^^
default:
assertUnreachable(optionalProp);
>assertUnreachable(optionalProp) : never
> : ^^^^^
>assertUnreachable : (_: never) => never
> : ^^^^^^^^^^^^^^^^^^^
>optionalProp : never
> : ^^^^^
}
}
function assertUnreachable(_: never): never {
>assertUnreachable : (_: never) => never
> : ^^^^ ^^^^^
>_ : never
> : ^^^^^
throw new Error("Unreachable path taken");
>new Error("Unreachable path taken") : Error
> : ^^^^^
>Error : ErrorConstructor
> : ^^^^^^^^^^^^^^^^
>"Unreachable path taken" : "Unreachable path taken"
> : ^^^^^^^^^^^^^^^^^^^^^^^^
}

View File

@ -0,0 +1,75 @@
//// [tests/cases/compiler/narrowBySwitchDiscriminantUndefinedCase1.ts] ////
=== narrowBySwitchDiscriminantUndefinedCase1.ts ===
// https://github.com/microsoft/TypeScript/issues/57999
interface A {
>A : Symbol(A, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 0, 0))
optionalProp?: "hello";
>optionalProp : Symbol(A.optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 2, 13))
}
function func(arg: A) {
>func : Symbol(func, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 4, 1))
>arg : Symbol(arg, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 6, 14))
>A : Symbol(A, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 0, 0))
const { optionalProp } = arg;
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 7, 9))
>arg : Symbol(arg, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 6, 14))
switch (optionalProp) {
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 7, 9))
case undefined:
>undefined : Symbol(undefined)
return undefined;
>undefined : Symbol(undefined)
case "hello":
return "hello";
default:
assertUnreachable(optionalProp);
>assertUnreachable : Symbol(assertUnreachable, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 30, 1))
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 7, 9))
}
}
function func2() {
>func2 : Symbol(func2, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 17, 1))
const optionalProp = ["hello" as const][Math.random()];
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 20, 7))
>const : Symbol(const)
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
switch (optionalProp) {
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 20, 7))
case undefined:
>undefined : Symbol(undefined)
return undefined;
>undefined : Symbol(undefined)
case "hello":
return "hello";
default:
assertUnreachable(optionalProp);
>assertUnreachable : Symbol(assertUnreachable, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 30, 1))
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 20, 7))
}
}
function assertUnreachable(_: never): never {
>assertUnreachable : Symbol(assertUnreachable, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 30, 1))
>_ : Symbol(_, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 32, 27))
throw new Error("Unreachable path taken");
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
}

View File

@ -0,0 +1,124 @@
//// [tests/cases/compiler/narrowBySwitchDiscriminantUndefinedCase1.ts] ////
=== narrowBySwitchDiscriminantUndefinedCase1.ts ===
// https://github.com/microsoft/TypeScript/issues/57999
interface A {
optionalProp?: "hello";
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
}
function func(arg: A) {
>func : (arg: A) => "hello" | undefined
> : ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
>arg : A
> : ^
const { optionalProp } = arg;
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
>arg : A
> : ^
switch (optionalProp) {
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
case undefined:
>undefined : undefined
> : ^^^^^^^^^
return undefined;
>undefined : undefined
> : ^^^^^^^^^
case "hello":
>"hello" : "hello"
> : ^^^^^^^
return "hello";
>"hello" : "hello"
> : ^^^^^^^
default:
assertUnreachable(optionalProp);
>assertUnreachable(optionalProp) : never
> : ^^^^^
>assertUnreachable : (_: never) => never
> : ^^^^^^^^^^^^^^^^^^^
>optionalProp : never
> : ^^^^^
}
}
function func2() {
>func2 : () => "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
const optionalProp = ["hello" as const][Math.random()];
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
>["hello" as const][Math.random()] : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
>["hello" as const] : "hello"[]
> : ^^^^^^^^^
>"hello" as const : "hello"
> : ^^^^^^^
>"hello" : "hello"
> : ^^^^^^^
>Math.random() : number
> : ^^^^^^
>Math.random : () => number
> : ^^^^^^^^^^^^
>Math : Math
> : ^^^^
>random : () => number
> : ^^^^^^^^^^^^
switch (optionalProp) {
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
case undefined:
>undefined : undefined
> : ^^^^^^^^^
return undefined;
>undefined : undefined
> : ^^^^^^^^^
case "hello":
>"hello" : "hello"
> : ^^^^^^^
return "hello";
>"hello" : "hello"
> : ^^^^^^^
default:
assertUnreachable(optionalProp);
>assertUnreachable(optionalProp) : never
> : ^^^^^
>assertUnreachable : (_: never) => never
> : ^^^^^^^^^^^^^^^^^^^
>optionalProp : never
> : ^^^^^
}
}
function assertUnreachable(_: never): never {
>assertUnreachable : (_: never) => never
> : ^^^^ ^^^^^
>_ : never
> : ^^^^^
throw new Error("Unreachable path taken");
>new Error("Unreachable path taken") : Error
> : ^^^^^
>Error : ErrorConstructor
> : ^^^^^^^^^^^^^^^^
>"Unreachable path taken" : "Unreachable path taken"
> : ^^^^^^^^^^^^^^^^^^^^^^^^
}

View File

@ -0,0 +1,75 @@
//// [tests/cases/compiler/narrowBySwitchDiscriminantUndefinedCase1.ts] ////
=== narrowBySwitchDiscriminantUndefinedCase1.ts ===
// https://github.com/microsoft/TypeScript/issues/57999
interface A {
>A : Symbol(A, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 0, 0))
optionalProp?: "hello";
>optionalProp : Symbol(A.optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 2, 13))
}
function func(arg: A) {
>func : Symbol(func, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 4, 1))
>arg : Symbol(arg, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 6, 14))
>A : Symbol(A, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 0, 0))
const { optionalProp } = arg;
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 7, 9))
>arg : Symbol(arg, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 6, 14))
switch (optionalProp) {
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 7, 9))
case undefined:
>undefined : Symbol(undefined)
return undefined;
>undefined : Symbol(undefined)
case "hello":
return "hello";
default:
assertUnreachable(optionalProp);
>assertUnreachable : Symbol(assertUnreachable, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 30, 1))
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 7, 9))
}
}
function func2() {
>func2 : Symbol(func2, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 17, 1))
const optionalProp = ["hello" as const][Math.random()];
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 20, 7))
>const : Symbol(const)
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
switch (optionalProp) {
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 20, 7))
case undefined:
>undefined : Symbol(undefined)
return undefined;
>undefined : Symbol(undefined)
case "hello":
return "hello";
default:
assertUnreachable(optionalProp);
>assertUnreachable : Symbol(assertUnreachable, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 30, 1))
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 20, 7))
}
}
function assertUnreachable(_: never): never {
>assertUnreachable : Symbol(assertUnreachable, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 30, 1))
>_ : Symbol(_, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 32, 27))
throw new Error("Unreachable path taken");
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
}

View File

@ -0,0 +1,124 @@
//// [tests/cases/compiler/narrowBySwitchDiscriminantUndefinedCase1.ts] ////
=== narrowBySwitchDiscriminantUndefinedCase1.ts ===
// https://github.com/microsoft/TypeScript/issues/57999
interface A {
optionalProp?: "hello";
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
}
function func(arg: A) {
>func : (arg: A) => "hello" | undefined
> : ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
>arg : A
> : ^
const { optionalProp } = arg;
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
>arg : A
> : ^
switch (optionalProp) {
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
case undefined:
>undefined : undefined
> : ^^^^^^^^^
return undefined;
>undefined : undefined
> : ^^^^^^^^^
case "hello":
>"hello" : "hello"
> : ^^^^^^^
return "hello";
>"hello" : "hello"
> : ^^^^^^^
default:
assertUnreachable(optionalProp);
>assertUnreachable(optionalProp) : never
> : ^^^^^
>assertUnreachable : (_: never) => never
> : ^^^^^^^^^^^^^^^^^^^
>optionalProp : never
> : ^^^^^
}
}
function func2() {
>func2 : () => "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
const optionalProp = ["hello" as const][Math.random()];
>optionalProp : "hello"
> : ^^^^^^^
>["hello" as const][Math.random()] : "hello"
> : ^^^^^^^
>["hello" as const] : "hello"[]
> : ^^^^^^^^^
>"hello" as const : "hello"
> : ^^^^^^^
>"hello" : "hello"
> : ^^^^^^^
>Math.random() : number
> : ^^^^^^
>Math.random : () => number
> : ^^^^^^^^^^^^
>Math : Math
> : ^^^^
>random : () => number
> : ^^^^^^^^^^^^
switch (optionalProp) {
>optionalProp : "hello"
> : ^^^^^^^
case undefined:
>undefined : undefined
> : ^^^^^^^^^
return undefined;
>undefined : undefined
> : ^^^^^^^^^
case "hello":
>"hello" : "hello"
> : ^^^^^^^
return "hello";
>"hello" : "hello"
> : ^^^^^^^
default:
assertUnreachable(optionalProp);
>assertUnreachable(optionalProp) : never
> : ^^^^^
>assertUnreachable : (_: never) => never
> : ^^^^^^^^^^^^^^^^^^^
>optionalProp : never
> : ^^^^^
}
}
function assertUnreachable(_: never): never {
>assertUnreachable : (_: never) => never
> : ^^^^ ^^^^^
>_ : never
> : ^^^^^
throw new Error("Unreachable path taken");
>new Error("Unreachable path taken") : Error
> : ^^^^^
>Error : ErrorConstructor
> : ^^^^^^^^^^^^^^^^
>"Unreachable path taken" : "Unreachable path taken"
> : ^^^^^^^^^^^^^^^^^^^^^^^^
}

View File

@ -0,0 +1,75 @@
//// [tests/cases/compiler/narrowBySwitchDiscriminantUndefinedCase1.ts] ////
=== narrowBySwitchDiscriminantUndefinedCase1.ts ===
// https://github.com/microsoft/TypeScript/issues/57999
interface A {
>A : Symbol(A, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 0, 0))
optionalProp?: "hello";
>optionalProp : Symbol(A.optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 2, 13))
}
function func(arg: A) {
>func : Symbol(func, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 4, 1))
>arg : Symbol(arg, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 6, 14))
>A : Symbol(A, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 0, 0))
const { optionalProp } = arg;
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 7, 9))
>arg : Symbol(arg, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 6, 14))
switch (optionalProp) {
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 7, 9))
case undefined:
>undefined : Symbol(undefined)
return undefined;
>undefined : Symbol(undefined)
case "hello":
return "hello";
default:
assertUnreachable(optionalProp);
>assertUnreachable : Symbol(assertUnreachable, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 30, 1))
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 7, 9))
}
}
function func2() {
>func2 : Symbol(func2, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 17, 1))
const optionalProp = ["hello" as const][Math.random()];
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 20, 7))
>const : Symbol(const)
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
switch (optionalProp) {
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 20, 7))
case undefined:
>undefined : Symbol(undefined)
return undefined;
>undefined : Symbol(undefined)
case "hello":
return "hello";
default:
assertUnreachable(optionalProp);
>assertUnreachable : Symbol(assertUnreachable, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 30, 1))
>optionalProp : Symbol(optionalProp, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 20, 7))
}
}
function assertUnreachable(_: never): never {
>assertUnreachable : Symbol(assertUnreachable, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 30, 1))
>_ : Symbol(_, Decl(narrowBySwitchDiscriminantUndefinedCase1.ts, 32, 27))
throw new Error("Unreachable path taken");
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
}

View File

@ -0,0 +1,124 @@
//// [tests/cases/compiler/narrowBySwitchDiscriminantUndefinedCase1.ts] ////
=== narrowBySwitchDiscriminantUndefinedCase1.ts ===
// https://github.com/microsoft/TypeScript/issues/57999
interface A {
optionalProp?: "hello";
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
}
function func(arg: A) {
>func : (arg: A) => "hello" | undefined
> : ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
>arg : A
> : ^
const { optionalProp } = arg;
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
>arg : A
> : ^
switch (optionalProp) {
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
case undefined:
>undefined : undefined
> : ^^^^^^^^^
return undefined;
>undefined : undefined
> : ^^^^^^^^^
case "hello":
>"hello" : "hello"
> : ^^^^^^^
return "hello";
>"hello" : "hello"
> : ^^^^^^^
default:
assertUnreachable(optionalProp);
>assertUnreachable(optionalProp) : never
> : ^^^^^
>assertUnreachable : (_: never) => never
> : ^^^^^^^^^^^^^^^^^^^
>optionalProp : never
> : ^^^^^
}
}
function func2() {
>func2 : () => "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
const optionalProp = ["hello" as const][Math.random()];
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
>["hello" as const][Math.random()] : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
>["hello" as const] : "hello"[]
> : ^^^^^^^^^
>"hello" as const : "hello"
> : ^^^^^^^
>"hello" : "hello"
> : ^^^^^^^
>Math.random() : number
> : ^^^^^^
>Math.random : () => number
> : ^^^^^^^^^^^^
>Math : Math
> : ^^^^
>random : () => number
> : ^^^^^^^^^^^^
switch (optionalProp) {
>optionalProp : "hello" | undefined
> : ^^^^^^^^^^^^^^^^^^^
case undefined:
>undefined : undefined
> : ^^^^^^^^^
return undefined;
>undefined : undefined
> : ^^^^^^^^^
case "hello":
>"hello" : "hello"
> : ^^^^^^^
return "hello";
>"hello" : "hello"
> : ^^^^^^^
default:
assertUnreachable(optionalProp);
>assertUnreachable(optionalProp) : never
> : ^^^^^
>assertUnreachable : (_: never) => never
> : ^^^^^^^^^^^^^^^^^^^
>optionalProp : never
> : ^^^^^
}
}
function assertUnreachable(_: never): never {
>assertUnreachable : (_: never) => never
> : ^^^^ ^^^^^
>_ : never
> : ^^^^^
throw new Error("Unreachable path taken");
>new Error("Unreachable path taken") : Error
> : ^^^^^
>Error : ErrorConstructor
> : ^^^^^^^^^^^^^^^^
>"Unreachable path taken" : "Unreachable path taken"
> : ^^^^^^^^^^^^^^^^^^^^^^^^
}

View File

@ -0,0 +1,40 @@
// @strict: true
// @exactOptionalPropertyTypes: true, false
// @noUncheckedIndexedAccess: true, false
// @noEmit: true
// https://github.com/microsoft/TypeScript/issues/57999
interface A {
optionalProp?: "hello";
}
function func(arg: A) {
const { optionalProp } = arg;
switch (optionalProp) {
case undefined:
return undefined;
case "hello":
return "hello";
default:
assertUnreachable(optionalProp);
}
}
function func2() {
const optionalProp = ["hello" as const][Math.random()];
switch (optionalProp) {
case undefined:
return undefined;
case "hello":
return "hello";
default:
assertUnreachable(optionalProp);
}
}
function assertUnreachable(_: never): never {
throw new Error("Unreachable path taken");
}