Skip to content

Commit d3877d2

Browse files
authored
Redo in narrowing for intersections (#39637)
* Redo in-narrowing for intersections Still need to carve out an exception for globalThis * exempt globalThis from `in` narrowing
1 parent 32934a9 commit d3877d2

File tree

6 files changed

+72
-6
lines changed

6 files changed

+72
-6
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21475,7 +21475,9 @@ namespace ts {
2147521475
}
2147621476

2147721477
function narrowByInKeyword(type: Type, literal: LiteralExpression, assumeTrue: boolean) {
21478-
if (type.flags & (TypeFlags.Union | TypeFlags.Object) || isThisTypeParameter(type)) {
21478+
if (type.flags & (TypeFlags.Union | TypeFlags.Object)
21479+
|| isThisTypeParameter(type)
21480+
|| type.flags & TypeFlags.Intersection && every((type as IntersectionType).types, t => t.symbol !== globalThisSymbol)) {
2147921481
const propName = escapeLeadingUnderscores(literal.text);
2148021482
return filterType(type, t => isTypePresencePossible(t, propName, assumeTrue));
2148121483
}

tests/baselines/reference/inKeywordTypeguard.errors.txt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ tests/cases/compiler/inKeywordTypeguard.ts(74,32): error TS2339: Property 'a' do
1919
tests/cases/compiler/inKeywordTypeguard.ts(82,39): error TS2339: Property 'b' does not exist on type 'A'.
2020
tests/cases/compiler/inKeywordTypeguard.ts(84,39): error TS2339: Property 'a' does not exist on type 'B'.
2121
tests/cases/compiler/inKeywordTypeguard.ts(94,26): error TS2339: Property 'a' does not exist on type 'never'.
22-
tests/cases/compiler/inKeywordTypeguard.ts(103,13): error TS2322: Type '{ a: string; } & { b: string; }' is not assignable to type 'never'.
2322

2423

25-
==== tests/cases/compiler/inKeywordTypeguard.ts (18 errors) ====
24+
==== tests/cases/compiler/inKeywordTypeguard.ts (17 errors) ====
2625
class A { a: string; }
2726
class B { b: string; }
2827

@@ -164,8 +163,13 @@ tests/cases/compiler/inKeywordTypeguard.ts(103,13): error TS2322: Type '{ a: str
164163
let s: string = x.a;
165164
} else {
166165
let n: never = x;
167-
~
168-
!!! error TS2322: Type '{ a: string; } & { b: string; }' is not assignable to type 'never'.
166+
}
167+
}
168+
function negativeIntersectionTest() {
169+
if ("ontouchstart" in window) {
170+
window.ontouchstart
171+
} else {
172+
window.ontouchstart
169173
}
170174
}
171175

tests/baselines/reference/inKeywordTypeguard.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ function positiveIntersectionTest(x: { a: string } & { b: string }) {
104104
let n: never = x;
105105
}
106106
}
107+
function negativeIntersectionTest() {
108+
if ("ontouchstart" in window) {
109+
window.ontouchstart
110+
} else {
111+
window.ontouchstart
112+
}
113+
}
107114

108115

109116
//// [inKeywordTypeguard.js]
@@ -245,3 +252,11 @@ function positiveIntersectionTest(x) {
245252
var n = x;
246253
}
247254
}
255+
function negativeIntersectionTest() {
256+
if ("ontouchstart" in window) {
257+
window.ontouchstart;
258+
}
259+
else {
260+
window.ontouchstart;
261+
}
262+
}

tests/baselines/reference/inKeywordTypeguard.symbols

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,4 +261,22 @@ function positiveIntersectionTest(x: { a: string } & { b: string }) {
261261
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 98, 34))
262262
}
263263
}
264+
function negativeIntersectionTest() {
265+
>negativeIntersectionTest : Symbol(negativeIntersectionTest, Decl(inKeywordTypeguard.ts, 104, 1))
266+
267+
if ("ontouchstart" in window) {
268+
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
269+
270+
window.ontouchstart
271+
>window.ontouchstart : Symbol(ontouchstart, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
272+
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
273+
>ontouchstart : Symbol(ontouchstart, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
274+
275+
} else {
276+
window.ontouchstart
277+
>window.ontouchstart : Symbol(ontouchstart, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
278+
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
279+
>ontouchstart : Symbol(ontouchstart, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
280+
}
281+
}
264282

tests/baselines/reference/inKeywordTypeguard.types

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,27 @@ function positiveIntersectionTest(x: { a: string } & { b: string }) {
318318
} else {
319319
let n: never = x;
320320
>n : never
321-
>x : { a: string; } & { b: string; }
321+
>x : never
322+
}
323+
}
324+
function negativeIntersectionTest() {
325+
>negativeIntersectionTest : () => void
326+
327+
if ("ontouchstart" in window) {
328+
>"ontouchstart" in window : boolean
329+
>"ontouchstart" : "ontouchstart"
330+
>window : Window & typeof globalThis
331+
332+
window.ontouchstart
333+
>window.ontouchstart : ((this: GlobalEventHandlers, ev: TouchEvent) => any) & ((this: Window, ev: TouchEvent) => any)
334+
>window : Window & typeof globalThis
335+
>ontouchstart : ((this: GlobalEventHandlers, ev: TouchEvent) => any) & ((this: Window, ev: TouchEvent) => any)
336+
337+
} else {
338+
window.ontouchstart
339+
>window.ontouchstart : ((this: GlobalEventHandlers, ev: TouchEvent) => any) & ((this: Window, ev: TouchEvent) => any)
340+
>window : Window & typeof globalThis
341+
>ontouchstart : ((this: GlobalEventHandlers, ev: TouchEvent) => any) & ((this: Window, ev: TouchEvent) => any)
322342
}
323343
}
324344

tests/cases/compiler/inKeywordTypeguard.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,10 @@ function positiveIntersectionTest(x: { a: string } & { b: string }) {
103103
let n: never = x;
104104
}
105105
}
106+
function negativeIntersectionTest() {
107+
if ("ontouchstart" in window) {
108+
window.ontouchstart
109+
} else {
110+
window.ontouchstart
111+
}
112+
}

0 commit comments

Comments
 (0)