Skip to content

Commit 46e7ab4

Browse files
authored
fix typefacts of intersection (#47583)
1 parent 21bbb57 commit 46e7ab4

9 files changed

+157
-2
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ namespace ts {
135135
AllTypeofNE = TypeofNEString | TypeofNENumber | TypeofNEBigInt | TypeofNEBoolean | TypeofNESymbol | TypeofNEObject | TypeofNEFunction | NEUndefined,
136136
EmptyObjectFacts = All,
137137
// Masks
138-
OrFactsMask = TypeofEQFunction | TypeofEQObject | TypeofNEObject,
138+
OrFactsMask = TypeofEQFunction | TypeofNEObject,
139139
AndFactsMask = All & ~OrFactsMask,
140140
}
141141

@@ -22961,7 +22961,10 @@ namespace ts {
2296122961
(type === falseType || type === regularFalseType) ? TypeFacts.FalseStrictFacts : TypeFacts.TrueStrictFacts :
2296222962
(type === falseType || type === regularFalseType) ? TypeFacts.FalseFacts : TypeFacts.TrueFacts;
2296322963
}
22964-
if (flags & TypeFlags.Object && !ignoreObjects) {
22964+
if (flags & TypeFlags.Object) {
22965+
if (ignoreObjects) {
22966+
return TypeFacts.AndFactsMask; // This is the identity element for computing type facts of intersection.
22967+
}
2296522968
return getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type as ObjectType) ?
2296622969
strictNullChecks ? TypeFacts.EmptyObjectStrictFacts : TypeFacts.EmptyObjectFacts :
2296722970
isFunctionObjectType(type as ObjectType) ?

tests/baselines/reference/narrowingTypeofFunction.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ function f2<T>(x: (T & F) | T & string) {
1818
else {
1919
x;
2020
}
21+
}
22+
23+
function f3(x: { _foo: number } & number) {
24+
if (typeof x === "function") {
25+
x;
26+
}
2127
}
2228

2329
//// [narrowingTypeofFunction.js]
@@ -38,3 +44,8 @@ function f2(x) {
3844
x;
3945
}
4046
}
47+
function f3(x) {
48+
if (typeof x === "function") {
49+
x;
50+
}
51+
}

tests/baselines/reference/narrowingTypeofFunction.symbols

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,16 @@ function f2<T>(x: (T & F) | T & string) {
4343
>x : Symbol(x, Decl(narrowingTypeofFunction.ts, 12, 15))
4444
}
4545
}
46+
47+
function f3(x: { _foo: number } & number) {
48+
>f3 : Symbol(f3, Decl(narrowingTypeofFunction.ts, 19, 1))
49+
>x : Symbol(x, Decl(narrowingTypeofFunction.ts, 21, 12))
50+
>_foo : Symbol(_foo, Decl(narrowingTypeofFunction.ts, 21, 16))
51+
52+
if (typeof x === "function") {
53+
>x : Symbol(x, Decl(narrowingTypeofFunction.ts, 21, 12))
54+
55+
x;
56+
>x : Symbol(x, Decl(narrowingTypeofFunction.ts, 21, 12))
57+
}
58+
}

tests/baselines/reference/narrowingTypeofFunction.types

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,19 @@ function f2<T>(x: (T & F) | T & string) {
4242
>x : T & string
4343
}
4444
}
45+
46+
function f3(x: { _foo: number } & number) {
47+
>f3 : (x: { _foo: number;} & number) => void
48+
>x : { _foo: number; } & number
49+
>_foo : number
50+
51+
if (typeof x === "function") {
52+
>typeof x === "function" : boolean
53+
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
54+
>x : { _foo: number; } & number
55+
>"function" : "function"
56+
57+
x;
58+
>x : never
59+
}
60+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//// [narrowingTypeofObject.ts]
2+
interface F { (): string }
3+
4+
function test(x: number & { _foo: string }) {
5+
if (typeof x === 'object') {
6+
x;
7+
}
8+
}
9+
10+
function f1(x: F & { foo: number }) {
11+
if (typeof x !== "object") {
12+
x;
13+
}
14+
}
15+
16+
//// [narrowingTypeofObject.js]
17+
"use strict";
18+
function test(x) {
19+
if (typeof x === 'object') {
20+
x;
21+
}
22+
}
23+
function f1(x) {
24+
if (typeof x !== "object") {
25+
x;
26+
}
27+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
=== tests/cases/compiler/narrowingTypeofObject.ts ===
2+
interface F { (): string }
3+
>F : Symbol(F, Decl(narrowingTypeofObject.ts, 0, 0))
4+
5+
function test(x: number & { _foo: string }) {
6+
>test : Symbol(test, Decl(narrowingTypeofObject.ts, 0, 26))
7+
>x : Symbol(x, Decl(narrowingTypeofObject.ts, 2, 14))
8+
>_foo : Symbol(_foo, Decl(narrowingTypeofObject.ts, 2, 27))
9+
10+
if (typeof x === 'object') {
11+
>x : Symbol(x, Decl(narrowingTypeofObject.ts, 2, 14))
12+
13+
x;
14+
>x : Symbol(x, Decl(narrowingTypeofObject.ts, 2, 14))
15+
}
16+
}
17+
18+
function f1(x: F & { foo: number }) {
19+
>f1 : Symbol(f1, Decl(narrowingTypeofObject.ts, 6, 1))
20+
>x : Symbol(x, Decl(narrowingTypeofObject.ts, 8, 12))
21+
>F : Symbol(F, Decl(narrowingTypeofObject.ts, 0, 0))
22+
>foo : Symbol(foo, Decl(narrowingTypeofObject.ts, 8, 20))
23+
24+
if (typeof x !== "object") {
25+
>x : Symbol(x, Decl(narrowingTypeofObject.ts, 8, 12))
26+
27+
x;
28+
>x : Symbol(x, Decl(narrowingTypeofObject.ts, 8, 12))
29+
}
30+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
=== tests/cases/compiler/narrowingTypeofObject.ts ===
2+
interface F { (): string }
3+
4+
function test(x: number & { _foo: string }) {
5+
>test : (x: number & { _foo: string;}) => void
6+
>x : number & { _foo: string; }
7+
>_foo : string
8+
9+
if (typeof x === 'object') {
10+
>typeof x === 'object' : boolean
11+
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
12+
>x : number & { _foo: string; }
13+
>'object' : "object"
14+
15+
x;
16+
>x : never
17+
}
18+
}
19+
20+
function f1(x: F & { foo: number }) {
21+
>f1 : (x: F & { foo: number;}) => void
22+
>x : F & { foo: number; }
23+
>foo : number
24+
25+
if (typeof x !== "object") {
26+
>typeof x !== "object" : boolean
27+
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
28+
>x : F & { foo: number; }
29+
>"object" : "object"
30+
31+
x;
32+
>x : F & { foo: number; }
33+
}
34+
}

tests/cases/compiler/narrowingTypeofFunction.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,10 @@ function f2<T>(x: (T & F) | T & string) {
1919
else {
2020
x;
2121
}
22+
}
23+
24+
function f3(x: { _foo: number } & number) {
25+
if (typeof x === "function") {
26+
x;
27+
}
2228
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @strict: true
2+
3+
interface F { (): string }
4+
5+
function test(x: number & { _foo: string }) {
6+
if (typeof x === 'object') {
7+
x;
8+
}
9+
}
10+
11+
function f1(x: F & { foo: number }) {
12+
if (typeof x !== "object") {
13+
x;
14+
}
15+
}

0 commit comments

Comments
 (0)