diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4765c1aa33402..5f9a896a14f4b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26839,7 +26839,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function narrowTypeByLiteralExpression(type: Type, literal: LiteralExpression, assumeTrue: boolean) { return assumeTrue ? narrowTypeByTypeName(type, literal.text) : - getTypeWithFacts(type, typeofNEFacts.get(literal.text) || TypeFacts.TypeofNEHostObject); + getAdjustedTypeWithFacts(type, typeofNEFacts.get(literal.text) || TypeFacts.TypeofNEHostObject); } function narrowTypeBySwitchOptionalChainContainment(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number, clauseCheck: (type: Type) => boolean) { diff --git a/tests/baselines/reference/narrowingTypeofUndefined.symbols b/tests/baselines/reference/narrowingTypeofUndefined.symbols deleted file mode 100644 index 33a81259b6909..0000000000000 --- a/tests/baselines/reference/narrowingTypeofUndefined.symbols +++ /dev/null @@ -1,52 +0,0 @@ -=== tests/cases/compiler/narrowingTypeofUndefined.ts === -declare const a: { error: { prop: string }, result: undefined } | { error: undefined, result: { prop: number } } ->a : Symbol(a, Decl(narrowingTypeofUndefined.ts, 0, 13)) ->error : Symbol(error, Decl(narrowingTypeofUndefined.ts, 0, 18)) ->prop : Symbol(prop, Decl(narrowingTypeofUndefined.ts, 0, 27)) ->result : Symbol(result, Decl(narrowingTypeofUndefined.ts, 0, 43)) ->error : Symbol(error, Decl(narrowingTypeofUndefined.ts, 0, 67)) ->result : Symbol(result, Decl(narrowingTypeofUndefined.ts, 0, 85)) ->prop : Symbol(prop, Decl(narrowingTypeofUndefined.ts, 0, 95)) - -if (typeof a.error === 'undefined') { ->a.error : Symbol(error, Decl(narrowingTypeofUndefined.ts, 0, 18), Decl(narrowingTypeofUndefined.ts, 0, 67)) ->a : Symbol(a, Decl(narrowingTypeofUndefined.ts, 0, 13)) ->error : Symbol(error, Decl(narrowingTypeofUndefined.ts, 0, 18), Decl(narrowingTypeofUndefined.ts, 0, 67)) - - a.result.prop; // number ->a.result.prop : Symbol(prop, Decl(narrowingTypeofUndefined.ts, 0, 95)) ->a.result : Symbol(result, Decl(narrowingTypeofUndefined.ts, 0, 43), Decl(narrowingTypeofUndefined.ts, 0, 85)) ->a : Symbol(a, Decl(narrowingTypeofUndefined.ts, 0, 13)) ->result : Symbol(result, Decl(narrowingTypeofUndefined.ts, 0, 43), Decl(narrowingTypeofUndefined.ts, 0, 85)) ->prop : Symbol(prop, Decl(narrowingTypeofUndefined.ts, 0, 95)) -} -else { - a.error.prop; // string ->a.error.prop : Symbol(prop, Decl(narrowingTypeofUndefined.ts, 0, 27)) ->a.error : Symbol(error, Decl(narrowingTypeofUndefined.ts, 0, 18), Decl(narrowingTypeofUndefined.ts, 0, 67)) ->a : Symbol(a, Decl(narrowingTypeofUndefined.ts, 0, 13)) ->error : Symbol(error, Decl(narrowingTypeofUndefined.ts, 0, 18), Decl(narrowingTypeofUndefined.ts, 0, 67)) ->prop : Symbol(prop, Decl(narrowingTypeofUndefined.ts, 0, 27)) -} - -if (typeof a.error !== 'undefined') { ->a.error : Symbol(error, Decl(narrowingTypeofUndefined.ts, 0, 18), Decl(narrowingTypeofUndefined.ts, 0, 67)) ->a : Symbol(a, Decl(narrowingTypeofUndefined.ts, 0, 13)) ->error : Symbol(error, Decl(narrowingTypeofUndefined.ts, 0, 18), Decl(narrowingTypeofUndefined.ts, 0, 67)) - - a.error.prop; // string ->a.error.prop : Symbol(prop, Decl(narrowingTypeofUndefined.ts, 0, 27)) ->a.error : Symbol(error, Decl(narrowingTypeofUndefined.ts, 0, 18), Decl(narrowingTypeofUndefined.ts, 0, 67)) ->a : Symbol(a, Decl(narrowingTypeofUndefined.ts, 0, 13)) ->error : Symbol(error, Decl(narrowingTypeofUndefined.ts, 0, 18), Decl(narrowingTypeofUndefined.ts, 0, 67)) ->prop : Symbol(prop, Decl(narrowingTypeofUndefined.ts, 0, 27)) -} -else { - a.result.prop; // number ->a.result.prop : Symbol(prop, Decl(narrowingTypeofUndefined.ts, 0, 95)) ->a.result : Symbol(result, Decl(narrowingTypeofUndefined.ts, 0, 43), Decl(narrowingTypeofUndefined.ts, 0, 85)) ->a : Symbol(a, Decl(narrowingTypeofUndefined.ts, 0, 13)) ->result : Symbol(result, Decl(narrowingTypeofUndefined.ts, 0, 43), Decl(narrowingTypeofUndefined.ts, 0, 85)) ->prop : Symbol(prop, Decl(narrowingTypeofUndefined.ts, 0, 95)) -} - diff --git a/tests/baselines/reference/narrowingTypeofUndefined.js b/tests/baselines/reference/narrowingTypeofUndefined1.js similarity index 86% rename from tests/baselines/reference/narrowingTypeofUndefined.js rename to tests/baselines/reference/narrowingTypeofUndefined1.js index 16e2d3f37851b..dcd4e19dab9ef 100644 --- a/tests/baselines/reference/narrowingTypeofUndefined.js +++ b/tests/baselines/reference/narrowingTypeofUndefined1.js @@ -1,4 +1,4 @@ -//// [narrowingTypeofUndefined.ts] +//// [narrowingTypeofUndefined1.ts] declare const a: { error: { prop: string }, result: undefined } | { error: undefined, result: { prop: number } } if (typeof a.error === 'undefined') { @@ -16,7 +16,7 @@ else { } -//// [narrowingTypeofUndefined.js] +//// [narrowingTypeofUndefined1.js] if (typeof a.error === 'undefined') { a.result.prop; // number } diff --git a/tests/baselines/reference/narrowingTypeofUndefined1.symbols b/tests/baselines/reference/narrowingTypeofUndefined1.symbols new file mode 100644 index 0000000000000..1d1df6a2482d1 --- /dev/null +++ b/tests/baselines/reference/narrowingTypeofUndefined1.symbols @@ -0,0 +1,52 @@ +=== tests/cases/compiler/narrowingTypeofUndefined1.ts === +declare const a: { error: { prop: string }, result: undefined } | { error: undefined, result: { prop: number } } +>a : Symbol(a, Decl(narrowingTypeofUndefined1.ts, 0, 13)) +>error : Symbol(error, Decl(narrowingTypeofUndefined1.ts, 0, 18)) +>prop : Symbol(prop, Decl(narrowingTypeofUndefined1.ts, 0, 27)) +>result : Symbol(result, Decl(narrowingTypeofUndefined1.ts, 0, 43)) +>error : Symbol(error, Decl(narrowingTypeofUndefined1.ts, 0, 67)) +>result : Symbol(result, Decl(narrowingTypeofUndefined1.ts, 0, 85)) +>prop : Symbol(prop, Decl(narrowingTypeofUndefined1.ts, 0, 95)) + +if (typeof a.error === 'undefined') { +>a.error : Symbol(error, Decl(narrowingTypeofUndefined1.ts, 0, 18), Decl(narrowingTypeofUndefined1.ts, 0, 67)) +>a : Symbol(a, Decl(narrowingTypeofUndefined1.ts, 0, 13)) +>error : Symbol(error, Decl(narrowingTypeofUndefined1.ts, 0, 18), Decl(narrowingTypeofUndefined1.ts, 0, 67)) + + a.result.prop; // number +>a.result.prop : Symbol(prop, Decl(narrowingTypeofUndefined1.ts, 0, 95)) +>a.result : Symbol(result, Decl(narrowingTypeofUndefined1.ts, 0, 43), Decl(narrowingTypeofUndefined1.ts, 0, 85)) +>a : Symbol(a, Decl(narrowingTypeofUndefined1.ts, 0, 13)) +>result : Symbol(result, Decl(narrowingTypeofUndefined1.ts, 0, 43), Decl(narrowingTypeofUndefined1.ts, 0, 85)) +>prop : Symbol(prop, Decl(narrowingTypeofUndefined1.ts, 0, 95)) +} +else { + a.error.prop; // string +>a.error.prop : Symbol(prop, Decl(narrowingTypeofUndefined1.ts, 0, 27)) +>a.error : Symbol(error, Decl(narrowingTypeofUndefined1.ts, 0, 18), Decl(narrowingTypeofUndefined1.ts, 0, 67)) +>a : Symbol(a, Decl(narrowingTypeofUndefined1.ts, 0, 13)) +>error : Symbol(error, Decl(narrowingTypeofUndefined1.ts, 0, 18), Decl(narrowingTypeofUndefined1.ts, 0, 67)) +>prop : Symbol(prop, Decl(narrowingTypeofUndefined1.ts, 0, 27)) +} + +if (typeof a.error !== 'undefined') { +>a.error : Symbol(error, Decl(narrowingTypeofUndefined1.ts, 0, 18), Decl(narrowingTypeofUndefined1.ts, 0, 67)) +>a : Symbol(a, Decl(narrowingTypeofUndefined1.ts, 0, 13)) +>error : Symbol(error, Decl(narrowingTypeofUndefined1.ts, 0, 18), Decl(narrowingTypeofUndefined1.ts, 0, 67)) + + a.error.prop; // string +>a.error.prop : Symbol(prop, Decl(narrowingTypeofUndefined1.ts, 0, 27)) +>a.error : Symbol(error, Decl(narrowingTypeofUndefined1.ts, 0, 18), Decl(narrowingTypeofUndefined1.ts, 0, 67)) +>a : Symbol(a, Decl(narrowingTypeofUndefined1.ts, 0, 13)) +>error : Symbol(error, Decl(narrowingTypeofUndefined1.ts, 0, 18), Decl(narrowingTypeofUndefined1.ts, 0, 67)) +>prop : Symbol(prop, Decl(narrowingTypeofUndefined1.ts, 0, 27)) +} +else { + a.result.prop; // number +>a.result.prop : Symbol(prop, Decl(narrowingTypeofUndefined1.ts, 0, 95)) +>a.result : Symbol(result, Decl(narrowingTypeofUndefined1.ts, 0, 43), Decl(narrowingTypeofUndefined1.ts, 0, 85)) +>a : Symbol(a, Decl(narrowingTypeofUndefined1.ts, 0, 13)) +>result : Symbol(result, Decl(narrowingTypeofUndefined1.ts, 0, 43), Decl(narrowingTypeofUndefined1.ts, 0, 85)) +>prop : Symbol(prop, Decl(narrowingTypeofUndefined1.ts, 0, 95)) +} + diff --git a/tests/baselines/reference/narrowingTypeofUndefined.types b/tests/baselines/reference/narrowingTypeofUndefined1.types similarity index 94% rename from tests/baselines/reference/narrowingTypeofUndefined.types rename to tests/baselines/reference/narrowingTypeofUndefined1.types index 3a84e875be650..e5548f3827bbd 100644 --- a/tests/baselines/reference/narrowingTypeofUndefined.types +++ b/tests/baselines/reference/narrowingTypeofUndefined1.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/narrowingTypeofUndefined.ts === +=== tests/cases/compiler/narrowingTypeofUndefined1.ts === declare const a: { error: { prop: string }, result: undefined } | { error: undefined, result: { prop: number } } >a : { error: { prop: string;}; result: undefined; } | { error: undefined; result: { prop: number;}; } >error : { prop: string; } diff --git a/tests/baselines/reference/narrowingTypeofUndefined2.js b/tests/baselines/reference/narrowingTypeofUndefined2.js new file mode 100644 index 0000000000000..1a4af73b68ed1 --- /dev/null +++ b/tests/baselines/reference/narrowingTypeofUndefined2.js @@ -0,0 +1,35 @@ +//// [narrowingTypeofUndefined2.ts] +declare function takeArray(arr: Array): void; + +function fn | undefined>(arg: T) { + if (typeof arg !== "undefined") { + takeArray(arg); + const n: Array = arg; + + for (const p of arg) { } + const m = [...arg]; + } +} + + +//// [narrowingTypeofUndefined2.js] +"use strict"; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); +}; +function fn(arg) { + if (typeof arg !== "undefined") { + takeArray(arg); + var n = arg; + for (var _i = 0, arg_1 = arg; _i < arg_1.length; _i++) { + var p = arg_1[_i]; + } + var m = __spreadArray([], arg, true); + } +} diff --git a/tests/baselines/reference/narrowingTypeofUndefined2.symbols b/tests/baselines/reference/narrowingTypeofUndefined2.symbols new file mode 100644 index 0000000000000..83c3ce4c37511 --- /dev/null +++ b/tests/baselines/reference/narrowingTypeofUndefined2.symbols @@ -0,0 +1,35 @@ +=== tests/cases/compiler/narrowingTypeofUndefined2.ts === +declare function takeArray(arr: Array): void; +>takeArray : Symbol(takeArray, Decl(narrowingTypeofUndefined2.ts, 0, 0)) +>arr : Symbol(arr, Decl(narrowingTypeofUndefined2.ts, 0, 27)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +function fn | undefined>(arg: T) { +>fn : Symbol(fn, Decl(narrowingTypeofUndefined2.ts, 0, 54)) +>T : Symbol(T, Decl(narrowingTypeofUndefined2.ts, 2, 12)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(narrowingTypeofUndefined2.ts, 2, 50)) +>T : Symbol(T, Decl(narrowingTypeofUndefined2.ts, 2, 12)) + + if (typeof arg !== "undefined") { +>arg : Symbol(arg, Decl(narrowingTypeofUndefined2.ts, 2, 50)) + + takeArray(arg); +>takeArray : Symbol(takeArray, Decl(narrowingTypeofUndefined2.ts, 0, 0)) +>arg : Symbol(arg, Decl(narrowingTypeofUndefined2.ts, 2, 50)) + + const n: Array = arg; +>n : Symbol(n, Decl(narrowingTypeofUndefined2.ts, 5, 13)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(narrowingTypeofUndefined2.ts, 2, 50)) + + for (const p of arg) { } +>p : Symbol(p, Decl(narrowingTypeofUndefined2.ts, 7, 18)) +>arg : Symbol(arg, Decl(narrowingTypeofUndefined2.ts, 2, 50)) + + const m = [...arg]; +>m : Symbol(m, Decl(narrowingTypeofUndefined2.ts, 8, 13)) +>arg : Symbol(arg, Decl(narrowingTypeofUndefined2.ts, 2, 50)) + } +} + diff --git a/tests/baselines/reference/narrowingTypeofUndefined2.types b/tests/baselines/reference/narrowingTypeofUndefined2.types new file mode 100644 index 0000000000000..be9cc205daf06 --- /dev/null +++ b/tests/baselines/reference/narrowingTypeofUndefined2.types @@ -0,0 +1,36 @@ +=== tests/cases/compiler/narrowingTypeofUndefined2.ts === +declare function takeArray(arr: Array): void; +>takeArray : (arr: Array) => void +>arr : unknown[] + +function fn | undefined>(arg: T) { +>fn : (arg: T) => void +>arg : T + + if (typeof arg !== "undefined") { +>typeof arg !== "undefined" : boolean +>typeof arg : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>arg : T +>"undefined" : "undefined" + + takeArray(arg); +>takeArray(arg) : void +>takeArray : (arr: unknown[]) => void +>arg : unknown[] + + const n: Array = arg; +>n : unknown[] +>arg : unknown[] + + for (const p of arg) { } +>p : unknown +>arg : T & {} + + const m = [...arg]; +>m : (T & {})[number][] +>[...arg] : (T & {})[number][] +>...arg : unknown +>arg : T & {} + } +} + diff --git a/tests/cases/compiler/narrowingTypeofUndefined.ts b/tests/cases/compiler/narrowingTypeofUndefined1.ts similarity index 100% rename from tests/cases/compiler/narrowingTypeofUndefined.ts rename to tests/cases/compiler/narrowingTypeofUndefined1.ts diff --git a/tests/cases/compiler/narrowingTypeofUndefined2.ts b/tests/cases/compiler/narrowingTypeofUndefined2.ts new file mode 100644 index 0000000000000..f77f55f6574ec --- /dev/null +++ b/tests/cases/compiler/narrowingTypeofUndefined2.ts @@ -0,0 +1,12 @@ +// @strict: true +declare function takeArray(arr: Array): void; + +function fn | undefined>(arg: T) { + if (typeof arg !== "undefined") { + takeArray(arg); + const n: Array = arg; + + for (const p of arg) { } + const m = [...arg]; + } +}