From 2609521bce8cc3c103a81c9ceb06865f3b676f24 Mon Sep 17 00:00:00 2001 From: Jack Williams Date: Sat, 16 May 2020 15:34:33 +0100 Subject: [PATCH 1/3] Fix #38608 --- src/compiler/checker.ts | 2 +- .../reference/fixSignatureCaching.errors.txt | 5 +- .../reference/fixSignatureCaching.symbols | 2 + .../reference/fixSignatureCaching.types | 10 ++-- .../reference/inKeywordTypeguard.errors.txt | 22 +++++++ .../baselines/reference/inKeywordTypeguard.js | 41 +++++++++++++ .../reference/inKeywordTypeguard.symbols | 52 ++++++++++++++++ .../reference/inKeywordTypeguard.types | 60 +++++++++++++++++++ tests/cases/compiler/inKeywordTypeguard.ts | 22 +++++++ 9 files changed, 206 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ee6a3a81c903c..6ead865e58b19 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20691,7 +20691,7 @@ namespace ts { } function narrowByInKeyword(type: Type, literal: LiteralExpression, assumeTrue: boolean) { - if (type.flags & (TypeFlags.Union | TypeFlags.Object) || isThisTypeParameter(type)) { + if (type.flags & TypeFlags.Union || type.flags & TypeFlags.Object && declaredType.flags & TypeFlags.Union || isThisTypeParameter(type)) { const propName = escapeLeadingUnderscores(literal.text); return filterType(type, t => isTypePresencePossible(t, propName, assumeTrue)); } diff --git a/tests/baselines/reference/fixSignatureCaching.errors.txt b/tests/baselines/reference/fixSignatureCaching.errors.txt index 2130f39d6dd72..65a2d3b34ca69 100644 --- a/tests/baselines/reference/fixSignatureCaching.errors.txt +++ b/tests/baselines/reference/fixSignatureCaching.errors.txt @@ -3,7 +3,6 @@ tests/cases/conformance/fixSignatureCaching.ts(284,10): error TS2339: Property ' tests/cases/conformance/fixSignatureCaching.ts(293,10): error TS2339: Property 'FALLBACK_PHONE' does not exist on type '{}'. tests/cases/conformance/fixSignatureCaching.ts(294,10): error TS2339: Property 'FALLBACK_TABLET' does not exist on type '{}'. tests/cases/conformance/fixSignatureCaching.ts(295,10): error TS2339: Property 'FALLBACK_MOBILE' does not exist on type '{}'. -tests/cases/conformance/fixSignatureCaching.ts(301,17): error TS2339: Property 'isArray' does not exist on type 'never'. tests/cases/conformance/fixSignatureCaching.ts(330,74): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'. tests/cases/conformance/fixSignatureCaching.ts(369,10): error TS2339: Property 'findMatch' does not exist on type '{}'. tests/cases/conformance/fixSignatureCaching.ts(387,10): error TS2339: Property 'findMatches' does not exist on type '{}'. @@ -59,7 +58,7 @@ tests/cases/conformance/fixSignatureCaching.ts(981,16): error TS2304: Cannot fin tests/cases/conformance/fixSignatureCaching.ts(983,44): error TS2339: Property 'MobileDetect' does not exist on type 'Window & typeof globalThis'. -==== tests/cases/conformance/fixSignatureCaching.ts (59 errors) ==== +==== tests/cases/conformance/fixSignatureCaching.ts (58 errors) ==== // Repro from #10697 (function (define, undefined) { @@ -371,8 +370,6 @@ tests/cases/conformance/fixSignatureCaching.ts(983,44): error TS2339: Property ' isArray = 'isArray' in Array ? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : Array.isArray; - ~~~~~~~ -!!! error TS2339: Property 'isArray' does not exist on type 'never'. function equalIC(a, b) { return a != null && b != null && a.toLowerCase() === b.toLowerCase(); diff --git a/tests/baselines/reference/fixSignatureCaching.symbols b/tests/baselines/reference/fixSignatureCaching.symbols index 97efe41ce1205..0ec1d2c63aae8 100644 --- a/tests/baselines/reference/fixSignatureCaching.symbols +++ b/tests/baselines/reference/fixSignatureCaching.symbols @@ -825,7 +825,9 @@ define(function () { >value : Symbol(value, Decl(fixSignatureCaching.ts, 299, 20)) : Array.isArray; +>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --)) >Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --)) function equalIC(a, b) { >equalIC : Symbol(equalIC, Decl(fixSignatureCaching.ts, 300, 24)) diff --git a/tests/baselines/reference/fixSignatureCaching.types b/tests/baselines/reference/fixSignatureCaching.types index cf367966c0260..f15d27063824e 100644 --- a/tests/baselines/reference/fixSignatureCaching.types +++ b/tests/baselines/reference/fixSignatureCaching.types @@ -1127,9 +1127,9 @@ define(function () { >'[object Array]' : "[object Array]" isArray = 'isArray' in Array ->isArray = 'isArray' in Array ? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : Array.isArray : any +>isArray = 'isArray' in Array ? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : Array.isArray : (value: any) => boolean >isArray : any ->'isArray' in Array ? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : Array.isArray : any +>'isArray' in Array ? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : Array.isArray : (value: any) => boolean >'isArray' in Array : boolean >'isArray' : "isArray" >Array : ArrayConstructor @@ -1150,9 +1150,9 @@ define(function () { >'[object Array]' : "[object Array]" : Array.isArray; ->Array.isArray : any ->Array : never ->isArray : any +>Array.isArray : (arg: any) => arg is any[] +>Array : ArrayConstructor +>isArray : (arg: any) => arg is any[] function equalIC(a, b) { >equalIC : (a: any, b: any) => boolean diff --git a/tests/baselines/reference/inKeywordTypeguard.errors.txt b/tests/baselines/reference/inKeywordTypeguard.errors.txt index 5aa04b170426c..a450d55e785e6 100644 --- a/tests/baselines/reference/inKeywordTypeguard.errors.txt +++ b/tests/baselines/reference/inKeywordTypeguard.errors.txt @@ -168,4 +168,26 @@ tests/cases/compiler/inKeywordTypeguard.ts(103,13): error TS2322: Type '{ a: str !!! error TS2322: Type '{ a: string; } & { b: string; }' is not assignable to type 'never'. } } + + // Repro from #38608 + declare const error: Error; + if ('extra' in error) { + error // Still Error + } else { + error // Error + } + + function narrowsToNever(x: { l: number } | { r: number }) { + let v: number; + if ("l" in x) { + v = x.l; + } + else if ("r" in x) { + v = x.r; + } + else { + v = x + } + return v; + } \ No newline at end of file diff --git a/tests/baselines/reference/inKeywordTypeguard.js b/tests/baselines/reference/inKeywordTypeguard.js index 83499d7f54e3d..03a1a4097b8ba 100644 --- a/tests/baselines/reference/inKeywordTypeguard.js +++ b/tests/baselines/reference/inKeywordTypeguard.js @@ -104,6 +104,28 @@ function positiveIntersectionTest(x: { a: string } & { b: string }) { let n: never = x; } } + +// Repro from #38608 +declare const error: Error; +if ('extra' in error) { + error // Still Error +} else { + error // Error +} + +function narrowsToNever(x: { l: number } | { r: number }) { + let v: number; + if ("l" in x) { + v = x.l; + } + else if ("r" in x) { + v = x.r; + } + else { + v = x + } + return v; +} //// [inKeywordTypeguard.js] @@ -245,3 +267,22 @@ function positiveIntersectionTest(x) { var n = x; } } +if ('extra' in error) { + error; // Still Error +} +else { + error; // Error +} +function narrowsToNever(x) { + var v; + if ("l" in x) { + v = x.l; + } + else if ("r" in x) { + v = x.r; + } + else { + v = x; + } + return v; +} diff --git a/tests/baselines/reference/inKeywordTypeguard.symbols b/tests/baselines/reference/inKeywordTypeguard.symbols index ff79a4aa54efb..f06165e9cb89b 100644 --- a/tests/baselines/reference/inKeywordTypeguard.symbols +++ b/tests/baselines/reference/inKeywordTypeguard.symbols @@ -262,3 +262,55 @@ function positiveIntersectionTest(x: { a: string } & { b: string }) { } } +// Repro from #38608 +declare const error: Error; +>error : Symbol(error, Decl(inKeywordTypeguard.ts, 107, 13)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +if ('extra' in error) { +>error : Symbol(error, Decl(inKeywordTypeguard.ts, 107, 13)) + + error // Still Error +>error : Symbol(error, Decl(inKeywordTypeguard.ts, 107, 13)) + +} else { + error // Error +>error : Symbol(error, Decl(inKeywordTypeguard.ts, 107, 13)) +} + +function narrowsToNever(x: { l: number } | { r: number }) { +>narrowsToNever : Symbol(narrowsToNever, Decl(inKeywordTypeguard.ts, 112, 1)) +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 114, 24)) +>l : Symbol(l, Decl(inKeywordTypeguard.ts, 114, 28)) +>r : Symbol(r, Decl(inKeywordTypeguard.ts, 114, 44)) + + let v: number; +>v : Symbol(v, Decl(inKeywordTypeguard.ts, 115, 7)) + + if ("l" in x) { +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 114, 24)) + + v = x.l; +>v : Symbol(v, Decl(inKeywordTypeguard.ts, 115, 7)) +>x.l : Symbol(l, Decl(inKeywordTypeguard.ts, 114, 28)) +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 114, 24)) +>l : Symbol(l, Decl(inKeywordTypeguard.ts, 114, 28)) + } + else if ("r" in x) { +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 114, 24)) + + v = x.r; +>v : Symbol(v, Decl(inKeywordTypeguard.ts, 115, 7)) +>x.r : Symbol(r, Decl(inKeywordTypeguard.ts, 114, 44)) +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 114, 24)) +>r : Symbol(r, Decl(inKeywordTypeguard.ts, 114, 44)) + } + else { + v = x +>v : Symbol(v, Decl(inKeywordTypeguard.ts, 115, 7)) +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 114, 24)) + } + return v; +>v : Symbol(v, Decl(inKeywordTypeguard.ts, 115, 7)) +} + diff --git a/tests/baselines/reference/inKeywordTypeguard.types b/tests/baselines/reference/inKeywordTypeguard.types index b15ab47d454e2..af24919f503e5 100644 --- a/tests/baselines/reference/inKeywordTypeguard.types +++ b/tests/baselines/reference/inKeywordTypeguard.types @@ -322,3 +322,63 @@ function positiveIntersectionTest(x: { a: string } & { b: string }) { } } +// Repro from #38608 +declare const error: Error; +>error : Error + +if ('extra' in error) { +>'extra' in error : boolean +>'extra' : "extra" +>error : Error + + error // Still Error +>error : Error + +} else { + error // Error +>error : Error +} + +function narrowsToNever(x: { l: number } | { r: number }) { +>narrowsToNever : (x: { l: number;} | { r: number;}) => number +>x : { l: number; } | { r: number; } +>l : number +>r : number + + let v: number; +>v : number + + if ("l" in x) { +>"l" in x : boolean +>"l" : "l" +>x : { l: number; } | { r: number; } + + v = x.l; +>v = x.l : number +>v : number +>x.l : number +>x : { l: number; } +>l : number + } + else if ("r" in x) { +>"r" in x : boolean +>"r" : "r" +>x : { r: number; } + + v = x.r; +>v = x.r : number +>v : number +>x.r : number +>x : { r: number; } +>r : number + } + else { + v = x +>v = x : never +>v : number +>x : never + } + return v; +>v : number +} + diff --git a/tests/cases/compiler/inKeywordTypeguard.ts b/tests/cases/compiler/inKeywordTypeguard.ts index 620aa401b252e..718b2f73a4636 100644 --- a/tests/cases/compiler/inKeywordTypeguard.ts +++ b/tests/cases/compiler/inKeywordTypeguard.ts @@ -103,3 +103,25 @@ function positiveIntersectionTest(x: { a: string } & { b: string }) { let n: never = x; } } + +// Repro from #38608 +declare const error: Error; +if ('extra' in error) { + error // Still Error +} else { + error // Error +} + +function narrowsToNever(x: { l: number } | { r: number }) { + let v: number; + if ("l" in x) { + v = x.l; + } + else if ("r" in x) { + v = x.r; + } + else { + v = x + } + return v; +} From 0525882cc0f94f854d974674f53631bb3bfdd9a1 Mon Sep 17 00:00:00 2001 From: Jack Williams Date: Tue, 19 May 2020 22:47:37 +0100 Subject: [PATCH 2/3] Work for narrowed non-unions --- src/compiler/checker.ts | 2 +- .../reference/inKeywordTypeguard.errors.txt | 16 +++++++ .../baselines/reference/inKeywordTypeguard.js | 27 +++++++++++ .../reference/inKeywordTypeguard.symbols | 43 +++++++++++++++++ .../reference/inKeywordTypeguard.types | 48 +++++++++++++++++++ tests/cases/compiler/inKeywordTypeguard.ts | 16 +++++++ 6 files changed, 151 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6ead865e58b19..a865317a23b03 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20691,7 +20691,7 @@ namespace ts { } function narrowByInKeyword(type: Type, literal: LiteralExpression, assumeTrue: boolean) { - if (type.flags & TypeFlags.Union || type.flags & TypeFlags.Object && declaredType.flags & TypeFlags.Union || isThisTypeParameter(type)) { + if (type.flags & TypeFlags.Union || type.flags & TypeFlags.Object && declaredType !== type || isThisTypeParameter(type)) { const propName = escapeLeadingUnderscores(literal.text); return filterType(type, t => isTypePresencePossible(t, propName, assumeTrue)); } diff --git a/tests/baselines/reference/inKeywordTypeguard.errors.txt b/tests/baselines/reference/inKeywordTypeguard.errors.txt index a450d55e785e6..93314aa7cc360 100644 --- a/tests/baselines/reference/inKeywordTypeguard.errors.txt +++ b/tests/baselines/reference/inKeywordTypeguard.errors.txt @@ -190,4 +190,20 @@ tests/cases/compiler/inKeywordTypeguard.ts(103,13): error TS2322: Type '{ a: str } return v; } + + type AOrB = { aProp: number } | { bProp: number }; + declare function isAOrB(x: unknown): x is AOrB; + + declare var x: unknown; + if (isAOrB(x)) { + if ("aProp" in x) { + x.aProp; + } + else if ("bProp" in x) { + x.bProp; + } + else if ("cProp" in x) { + const _never: never = x; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/inKeywordTypeguard.js b/tests/baselines/reference/inKeywordTypeguard.js index 03a1a4097b8ba..3fdea34ca0e70 100644 --- a/tests/baselines/reference/inKeywordTypeguard.js +++ b/tests/baselines/reference/inKeywordTypeguard.js @@ -126,6 +126,22 @@ function narrowsToNever(x: { l: number } | { r: number }) { } return v; } + +type AOrB = { aProp: number } | { bProp: number }; +declare function isAOrB(x: unknown): x is AOrB; + +declare var x: unknown; +if (isAOrB(x)) { + if ("aProp" in x) { + x.aProp; + } + else if ("bProp" in x) { + x.bProp; + } + else if ("cProp" in x) { + const _never: never = x; + } +} //// [inKeywordTypeguard.js] @@ -286,3 +302,14 @@ function narrowsToNever(x) { } return v; } +if (isAOrB(x)) { + if ("aProp" in x) { + x.aProp; + } + else if ("bProp" in x) { + x.bProp; + } + else if ("cProp" in x) { + var _never = x; + } +} diff --git a/tests/baselines/reference/inKeywordTypeguard.symbols b/tests/baselines/reference/inKeywordTypeguard.symbols index f06165e9cb89b..bf2003b322ac6 100644 --- a/tests/baselines/reference/inKeywordTypeguard.symbols +++ b/tests/baselines/reference/inKeywordTypeguard.symbols @@ -314,3 +314,46 @@ function narrowsToNever(x: { l: number } | { r: number }) { >v : Symbol(v, Decl(inKeywordTypeguard.ts, 115, 7)) } +type AOrB = { aProp: number } | { bProp: number }; +>AOrB : Symbol(AOrB, Decl(inKeywordTypeguard.ts, 126, 1)) +>aProp : Symbol(aProp, Decl(inKeywordTypeguard.ts, 128, 13)) +>bProp : Symbol(bProp, Decl(inKeywordTypeguard.ts, 128, 33)) + +declare function isAOrB(x: unknown): x is AOrB; +>isAOrB : Symbol(isAOrB, Decl(inKeywordTypeguard.ts, 128, 50)) +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 129, 24)) +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 129, 24)) +>AOrB : Symbol(AOrB, Decl(inKeywordTypeguard.ts, 126, 1)) + +declare var x: unknown; +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11)) + +if (isAOrB(x)) { +>isAOrB : Symbol(isAOrB, Decl(inKeywordTypeguard.ts, 128, 50)) +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11)) + + if ("aProp" in x) { +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11)) + + x.aProp; +>x.aProp : Symbol(aProp, Decl(inKeywordTypeguard.ts, 128, 13)) +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11)) +>aProp : Symbol(aProp, Decl(inKeywordTypeguard.ts, 128, 13)) + } + else if ("bProp" in x) { +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11)) + + x.bProp; +>x.bProp : Symbol(bProp, Decl(inKeywordTypeguard.ts, 128, 33)) +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11)) +>bProp : Symbol(bProp, Decl(inKeywordTypeguard.ts, 128, 33)) + } + else if ("cProp" in x) { +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11)) + + const _never: never = x; +>_never : Symbol(_never, Decl(inKeywordTypeguard.ts, 140, 13)) +>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11)) + } +} + diff --git a/tests/baselines/reference/inKeywordTypeguard.types b/tests/baselines/reference/inKeywordTypeguard.types index af24919f503e5..dcbc28708a14b 100644 --- a/tests/baselines/reference/inKeywordTypeguard.types +++ b/tests/baselines/reference/inKeywordTypeguard.types @@ -382,3 +382,51 @@ function narrowsToNever(x: { l: number } | { r: number }) { >v : number } +type AOrB = { aProp: number } | { bProp: number }; +>AOrB : AOrB +>aProp : number +>bProp : number + +declare function isAOrB(x: unknown): x is AOrB; +>isAOrB : (x: unknown) => x is AOrB +>x : unknown + +declare var x: unknown; +>x : unknown + +if (isAOrB(x)) { +>isAOrB(x) : boolean +>isAOrB : (x: unknown) => x is AOrB +>x : unknown + + if ("aProp" in x) { +>"aProp" in x : boolean +>"aProp" : "aProp" +>x : AOrB + + x.aProp; +>x.aProp : number +>x : { aProp: number; } +>aProp : number + } + else if ("bProp" in x) { +>"bProp" in x : boolean +>"bProp" : "bProp" +>x : { bProp: number; } + + x.bProp; +>x.bProp : number +>x : { bProp: number; } +>bProp : number + } + else if ("cProp" in x) { +>"cProp" in x : boolean +>"cProp" : "cProp" +>x : never + + const _never: never = x; +>_never : never +>x : never + } +} + diff --git a/tests/cases/compiler/inKeywordTypeguard.ts b/tests/cases/compiler/inKeywordTypeguard.ts index 718b2f73a4636..62f71f02293ce 100644 --- a/tests/cases/compiler/inKeywordTypeguard.ts +++ b/tests/cases/compiler/inKeywordTypeguard.ts @@ -125,3 +125,19 @@ function narrowsToNever(x: { l: number } | { r: number }) { } return v; } + +type AOrB = { aProp: number } | { bProp: number }; +declare function isAOrB(x: unknown): x is AOrB; + +declare var x: unknown; +if (isAOrB(x)) { + if ("aProp" in x) { + x.aProp; + } + else if ("bProp" in x) { + x.bProp; + } + else if ("cProp" in x) { + const _never: never = x; + } +} From 640cb2e11816a621e56e34fdd18dbe1628ce8b53 Mon Sep 17 00:00:00 2001 From: Jack Williams Date: Tue, 10 Nov 2020 16:46:44 +0000 Subject: [PATCH 3/3] Add comment --- tests/baselines/reference/inKeywordTypeguard.errors.txt | 1 + tests/baselines/reference/inKeywordTypeguard.js | 2 ++ tests/baselines/reference/inKeywordTypeguard.symbols | 5 +++-- tests/baselines/reference/inKeywordTypeguard.types | 1 + tests/cases/compiler/inKeywordTypeguard.ts | 1 + 5 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/inKeywordTypeguard.errors.txt b/tests/baselines/reference/inKeywordTypeguard.errors.txt index 2b0e943e72ce7..cfb2b090a7af5 100644 --- a/tests/baselines/reference/inKeywordTypeguard.errors.txt +++ b/tests/baselines/reference/inKeywordTypeguard.errors.txt @@ -199,6 +199,7 @@ tests/cases/compiler/inKeywordTypeguard.ts(94,26): error TS2339: Property 'a' do else if ("bProp" in x) { x.bProp; } + // x is never because of the type predicate from unknown else if ("cProp" in x) { const _never: never = x; } diff --git a/tests/baselines/reference/inKeywordTypeguard.js b/tests/baselines/reference/inKeywordTypeguard.js index 46fda80cef2fa..e91a6ddf6e4d4 100644 --- a/tests/baselines/reference/inKeywordTypeguard.js +++ b/tests/baselines/reference/inKeywordTypeguard.js @@ -138,6 +138,7 @@ if (isAOrB(x)) { else if ("bProp" in x) { x.bProp; } + // x is never because of the type predicate from unknown else if ("cProp" in x) { const _never: never = x; } @@ -317,6 +318,7 @@ if (isAOrB(x)) { else if ("bProp" in x) { x.bProp; } + // x is never because of the type predicate from unknown else if ("cProp" in x) { var _never = x; } diff --git a/tests/baselines/reference/inKeywordTypeguard.symbols b/tests/baselines/reference/inKeywordTypeguard.symbols index 6845ff15efbc8..91d9c42597740 100644 --- a/tests/baselines/reference/inKeywordTypeguard.symbols +++ b/tests/baselines/reference/inKeywordTypeguard.symbols @@ -348,17 +348,18 @@ if (isAOrB(x)) { >x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11)) >bProp : Symbol(bProp, Decl(inKeywordTypeguard.ts, 128, 33)) } + // x is never because of the type predicate from unknown else if ("cProp" in x) { >x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11)) const _never: never = x; ->_never : Symbol(_never, Decl(inKeywordTypeguard.ts, 140, 13)) +>_never : Symbol(_never, Decl(inKeywordTypeguard.ts, 141, 13)) >x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11)) } } function negativeIntersectionTest() { ->negativeIntersectionTest : Symbol(negativeIntersectionTest, Decl(inKeywordTypeguard.ts, 142, 1)) +>negativeIntersectionTest : Symbol(negativeIntersectionTest, Decl(inKeywordTypeguard.ts, 143, 1)) if ("ontouchstart" in window) { >window : Symbol(window, Decl(lib.dom.d.ts, --, --)) diff --git a/tests/baselines/reference/inKeywordTypeguard.types b/tests/baselines/reference/inKeywordTypeguard.types index 772c3a361fc37..e0956d838e2ec 100644 --- a/tests/baselines/reference/inKeywordTypeguard.types +++ b/tests/baselines/reference/inKeywordTypeguard.types @@ -419,6 +419,7 @@ if (isAOrB(x)) { >x : { bProp: number; } >bProp : number } + // x is never because of the type predicate from unknown else if ("cProp" in x) { >"cProp" in x : boolean >"cProp" : "cProp" diff --git a/tests/cases/compiler/inKeywordTypeguard.ts b/tests/cases/compiler/inKeywordTypeguard.ts index d980f48050087..e853d1935bee7 100644 --- a/tests/cases/compiler/inKeywordTypeguard.ts +++ b/tests/cases/compiler/inKeywordTypeguard.ts @@ -137,6 +137,7 @@ if (isAOrB(x)) { else if ("bProp" in x) { x.bProp; } + // x is never because of the type predicate from unknown else if ("cProp" in x) { const _never: never = x; }