Skip to content

Commit a46e9ae

Browse files
authored
support 'in' type guard of intersections (microsoft#37106)
1 parent 23b500c commit a46e9ae

File tree

6 files changed

+86
-4
lines changed

6 files changed

+86
-4
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20241,7 +20241,7 @@ namespace ts {
2024120241
}
2024220242

2024320243
function narrowByInKeyword(type: Type, literal: LiteralExpression, assumeTrue: boolean) {
20244-
if (type.flags & (TypeFlags.Union | TypeFlags.Object) || isThisTypeParameter(type)) {
20244+
if (type.flags & (TypeFlags.Union | TypeFlags.Object | TypeFlags.Intersection) || isThisTypeParameter(type)) {
2024520245
const propName = escapeLeadingUnderscores(literal.text);
2024620246
return filterType(type, t => isTypePresencePossible(t, propName, assumeTrue));
2024720247
}

tests/baselines/reference/inKeywordTypeguard.errors.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,13 @@ tests/cases/compiler/inKeywordTypeguard.ts(94,26): error TS2339: Property 'a' do
156156
!!! error TS2339: Property 'a' does not exist on type 'never'.
157157
}
158158
}
159-
}
159+
}
160+
161+
function positiveIntersectionTest(x: { a: string } & { b: string }) {
162+
if ("a" in x) {
163+
let s: string = x.a;
164+
} else {
165+
let n: never = x;
166+
}
167+
}
168+

tests/baselines/reference/inKeywordTypeguard.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,16 @@ class UnreachableCodeDetection {
9595
let y = this.a;
9696
}
9797
}
98-
}
98+
}
99+
100+
function positiveIntersectionTest(x: { a: string } & { b: string }) {
101+
if ("a" in x) {
102+
let s: string = x.a;
103+
} else {
104+
let n: never = x;
105+
}
106+
}
107+
99108

100109
//// [inKeywordTypeguard.js]
101110
var A = /** @class */ (function () {
@@ -228,3 +237,11 @@ var UnreachableCodeDetection = /** @class */ (function () {
228237
};
229238
return UnreachableCodeDetection;
230239
}());
240+
function positiveIntersectionTest(x) {
241+
if ("a" in x) {
242+
var s = x.a;
243+
}
244+
else {
245+
var n = x;
246+
}
247+
}

tests/baselines/reference/inKeywordTypeguard.symbols

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,3 +239,26 @@ class UnreachableCodeDetection {
239239
}
240240
}
241241
}
242+
243+
function positiveIntersectionTest(x: { a: string } & { b: string }) {
244+
>positiveIntersectionTest : Symbol(positiveIntersectionTest, Decl(inKeywordTypeguard.ts, 96, 1))
245+
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 98, 34))
246+
>a : Symbol(a, Decl(inKeywordTypeguard.ts, 98, 38))
247+
>b : Symbol(b, Decl(inKeywordTypeguard.ts, 98, 54))
248+
249+
if ("a" in x) {
250+
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 98, 34))
251+
252+
let s: string = x.a;
253+
>s : Symbol(s, Decl(inKeywordTypeguard.ts, 100, 11))
254+
>x.a : Symbol(a, Decl(inKeywordTypeguard.ts, 98, 38))
255+
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 98, 34))
256+
>a : Symbol(a, Decl(inKeywordTypeguard.ts, 98, 38))
257+
258+
} else {
259+
let n: never = x;
260+
>n : Symbol(n, Decl(inKeywordTypeguard.ts, 102, 11))
261+
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 98, 34))
262+
}
263+
}
264+

tests/baselines/reference/inKeywordTypeguard.types

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,3 +297,28 @@ class UnreachableCodeDetection {
297297
}
298298
}
299299
}
300+
301+
function positiveIntersectionTest(x: { a: string } & { b: string }) {
302+
>positiveIntersectionTest : (x: { a: string; } & { b: string; }) => void
303+
>x : { a: string; } & { b: string; }
304+
>a : string
305+
>b : string
306+
307+
if ("a" in x) {
308+
>"a" in x : boolean
309+
>"a" : "a"
310+
>x : { a: string; } & { b: string; }
311+
312+
let s: string = x.a;
313+
>s : string
314+
>x.a : string
315+
>x : { a: string; } & { b: string; }
316+
>a : string
317+
318+
} else {
319+
let n: never = x;
320+
>n : never
321+
>x : never
322+
}
323+
}
324+

tests/cases/compiler/inKeywordTypeguard.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,12 @@ class UnreachableCodeDetection {
9494
let y = this.a;
9595
}
9696
}
97-
}
97+
}
98+
99+
function positiveIntersectionTest(x: { a: string } & { b: string }) {
100+
if ("a" in x) {
101+
let s: string = x.a;
102+
} else {
103+
let n: never = x;
104+
}
105+
}

0 commit comments

Comments
 (0)