Skip to content

Commit 8d0c72d

Browse files
authored
Normalize effective constraint intersection before checking if source is a part of it (#49956)
1 parent adfb20f commit 8d0c72d

10 files changed

+541
-1
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12124,7 +12124,8 @@ namespace ts {
1212412124
}
1212512125
}
1212612126
}
12127-
return getIntersectionType(constraints);
12127+
// The source types were normalized; ensure the result is normalized too.
12128+
return getNormalizedType(getIntersectionType(constraints), /*writing*/ false);
1212812129
}
1212912130
return undefined;
1213012131
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//// [instanceofTypeAliasToGenericClass.ts]
2+
declare class TableClass<S = any> {
3+
_field: S;
4+
}
5+
6+
export type Table = TableClass;
7+
8+
function fn<T extends Table>(o: T) {
9+
return o instanceof TableClass;
10+
}
11+
12+
function fn2<T extends TableClass>(o: T) {
13+
return o instanceof TableClass;
14+
}
15+
16+
declare const o: Table;
17+
o instanceof TableClass;
18+
19+
20+
//// [instanceofTypeAliasToGenericClass.js]
21+
"use strict";
22+
exports.__esModule = true;
23+
function fn(o) {
24+
return o instanceof TableClass;
25+
}
26+
function fn2(o) {
27+
return o instanceof TableClass;
28+
}
29+
o instanceof TableClass;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
=== tests/cases/compiler/instanceofTypeAliasToGenericClass.ts ===
2+
declare class TableClass<S = any> {
3+
>TableClass : Symbol(TableClass, Decl(instanceofTypeAliasToGenericClass.ts, 0, 0))
4+
>S : Symbol(S, Decl(instanceofTypeAliasToGenericClass.ts, 0, 25))
5+
6+
_field: S;
7+
>_field : Symbol(TableClass._field, Decl(instanceofTypeAliasToGenericClass.ts, 0, 35))
8+
>S : Symbol(S, Decl(instanceofTypeAliasToGenericClass.ts, 0, 25))
9+
}
10+
11+
export type Table = TableClass;
12+
>Table : Symbol(Table, Decl(instanceofTypeAliasToGenericClass.ts, 2, 1))
13+
>TableClass : Symbol(TableClass, Decl(instanceofTypeAliasToGenericClass.ts, 0, 0))
14+
15+
function fn<T extends Table>(o: T) {
16+
>fn : Symbol(fn, Decl(instanceofTypeAliasToGenericClass.ts, 4, 31))
17+
>T : Symbol(T, Decl(instanceofTypeAliasToGenericClass.ts, 6, 12))
18+
>Table : Symbol(Table, Decl(instanceofTypeAliasToGenericClass.ts, 2, 1))
19+
>o : Symbol(o, Decl(instanceofTypeAliasToGenericClass.ts, 6, 29))
20+
>T : Symbol(T, Decl(instanceofTypeAliasToGenericClass.ts, 6, 12))
21+
22+
return o instanceof TableClass;
23+
>o : Symbol(o, Decl(instanceofTypeAliasToGenericClass.ts, 6, 29))
24+
>TableClass : Symbol(TableClass, Decl(instanceofTypeAliasToGenericClass.ts, 0, 0))
25+
}
26+
27+
function fn2<T extends TableClass>(o: T) {
28+
>fn2 : Symbol(fn2, Decl(instanceofTypeAliasToGenericClass.ts, 8, 1))
29+
>T : Symbol(T, Decl(instanceofTypeAliasToGenericClass.ts, 10, 13))
30+
>TableClass : Symbol(TableClass, Decl(instanceofTypeAliasToGenericClass.ts, 0, 0))
31+
>o : Symbol(o, Decl(instanceofTypeAliasToGenericClass.ts, 10, 35))
32+
>T : Symbol(T, Decl(instanceofTypeAliasToGenericClass.ts, 10, 13))
33+
34+
return o instanceof TableClass;
35+
>o : Symbol(o, Decl(instanceofTypeAliasToGenericClass.ts, 10, 35))
36+
>TableClass : Symbol(TableClass, Decl(instanceofTypeAliasToGenericClass.ts, 0, 0))
37+
}
38+
39+
declare const o: Table;
40+
>o : Symbol(o, Decl(instanceofTypeAliasToGenericClass.ts, 14, 13))
41+
>Table : Symbol(Table, Decl(instanceofTypeAliasToGenericClass.ts, 2, 1))
42+
43+
o instanceof TableClass;
44+
>o : Symbol(o, Decl(instanceofTypeAliasToGenericClass.ts, 14, 13))
45+
>TableClass : Symbol(TableClass, Decl(instanceofTypeAliasToGenericClass.ts, 0, 0))
46+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
=== tests/cases/compiler/instanceofTypeAliasToGenericClass.ts ===
2+
declare class TableClass<S = any> {
3+
>TableClass : TableClass<S>
4+
5+
_field: S;
6+
>_field : S
7+
}
8+
9+
export type Table = TableClass;
10+
>Table : TableClass<any>
11+
12+
function fn<T extends Table>(o: T) {
13+
>fn : <T extends Table>(o: T) => boolean
14+
>o : T
15+
16+
return o instanceof TableClass;
17+
>o instanceof TableClass : boolean
18+
>o : T
19+
>TableClass : typeof TableClass
20+
}
21+
22+
function fn2<T extends TableClass>(o: T) {
23+
>fn2 : <T extends TableClass<any>>(o: T) => boolean
24+
>o : T
25+
26+
return o instanceof TableClass;
27+
>o instanceof TableClass : boolean
28+
>o : T
29+
>TableClass : typeof TableClass
30+
}
31+
32+
declare const o: Table;
33+
>o : Table
34+
35+
o instanceof TableClass;
36+
>o instanceof TableClass : boolean
37+
>o : Table
38+
>TableClass : typeof TableClass
39+
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(21,5): error TS2322: Type 'T' is not assignable to type 'boolean'.
2+
Type 'TableClass<any>' is not assignable to type 'boolean'.
3+
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(22,5): error TS2322: Type 'T' is not assignable to type 'string | number'.
4+
Type 'TableClass<any>' is not assignable to type 'string | number'.
5+
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(23,5): error TS2322: Type 'T' is not assignable to type 'string | Something'.
6+
Type 'TableClass<any>' is not assignable to type 'string | Something'.
7+
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(24,5): error TS2322: Type 'T' is not assignable to type 'Something | SomethingElse'.
8+
Type 'TableClass<any>' is not assignable to type 'Something | SomethingElse'.
9+
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(28,5): error TS2322: Type 'T' is not assignable to type 'boolean'.
10+
Type 'TableClass<any>' is not assignable to type 'boolean'.
11+
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(29,5): error TS2322: Type 'T' is not assignable to type 'string | number'.
12+
Type 'TableClass<any>' is not assignable to type 'string | number'.
13+
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(30,5): error TS2322: Type 'T' is not assignable to type 'string | Something'.
14+
Type 'TableClass<any>' is not assignable to type 'string | Something'.
15+
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(31,5): error TS2322: Type 'T' is not assignable to type 'Something | SomethingElse'.
16+
Type 'TableClass<any>' is not assignable to type 'Something | SomethingElse'.
17+
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(35,1): error TS2322: Type 'Table' is not assignable to type 'boolean'.
18+
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(36,1): error TS2322: Type 'Table' is not assignable to type 'string | number'.
19+
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(37,1): error TS2322: Type 'Table' is not assignable to type 'string | Something'.
20+
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(38,1): error TS2322: Type 'Table' is not assignable to type 'Something | SomethingElse'.
21+
22+
23+
==== tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts (12 errors) ====
24+
declare class TableClass<S = any> {
25+
_field: S;
26+
}
27+
28+
export type Table = TableClass;
29+
30+
interface Something {
31+
prop: number;
32+
}
33+
34+
interface SomethingElse {
35+
prop2: string;
36+
}
37+
38+
declare let aBoolean: boolean;
39+
declare let aStringOrNumber: string | number;
40+
declare let aStringOrSomething: string | Something;
41+
declare let someUnion: Something | SomethingElse;
42+
43+
function fn<T extends Table>(o: T) {
44+
aBoolean = o;
45+
~~~~~~~~
46+
!!! error TS2322: Type 'T' is not assignable to type 'boolean'.
47+
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'boolean'.
48+
aStringOrNumber = o;
49+
~~~~~~~~~~~~~~~
50+
!!! error TS2322: Type 'T' is not assignable to type 'string | number'.
51+
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'string | number'.
52+
aStringOrSomething = o;
53+
~~~~~~~~~~~~~~~~~~
54+
!!! error TS2322: Type 'T' is not assignable to type 'string | Something'.
55+
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'string | Something'.
56+
someUnion = o;
57+
~~~~~~~~~
58+
!!! error TS2322: Type 'T' is not assignable to type 'Something | SomethingElse'.
59+
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'Something | SomethingElse'.
60+
}
61+
62+
function fn2<T extends TableClass>(o: T) {
63+
aBoolean = o;
64+
~~~~~~~~
65+
!!! error TS2322: Type 'T' is not assignable to type 'boolean'.
66+
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'boolean'.
67+
aStringOrNumber = o;
68+
~~~~~~~~~~~~~~~
69+
!!! error TS2322: Type 'T' is not assignable to type 'string | number'.
70+
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'string | number'.
71+
aStringOrSomething = o;
72+
~~~~~~~~~~~~~~~~~~
73+
!!! error TS2322: Type 'T' is not assignable to type 'string | Something'.
74+
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'string | Something'.
75+
someUnion = o;
76+
~~~~~~~~~
77+
!!! error TS2322: Type 'T' is not assignable to type 'Something | SomethingElse'.
78+
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'Something | SomethingElse'.
79+
}
80+
81+
declare const o: Table;
82+
aBoolean = o;
83+
~~~~~~~~
84+
!!! error TS2322: Type 'Table' is not assignable to type 'boolean'.
85+
aStringOrNumber = o;
86+
~~~~~~~~~~~~~~~
87+
!!! error TS2322: Type 'Table' is not assignable to type 'string | number'.
88+
aStringOrSomething = o;
89+
~~~~~~~~~~~~~~~~~~
90+
!!! error TS2322: Type 'Table' is not assignable to type 'string | Something'.
91+
someUnion = o;
92+
~~~~~~~~~
93+
!!! error TS2322: Type 'Table' is not assignable to type 'Something | SomethingElse'.
94+
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//// [typeVariableConstraintedToAliasNotAssignableToUnion.ts]
2+
declare class TableClass<S = any> {
3+
_field: S;
4+
}
5+
6+
export type Table = TableClass;
7+
8+
interface Something {
9+
prop: number;
10+
}
11+
12+
interface SomethingElse {
13+
prop2: string;
14+
}
15+
16+
declare let aBoolean: boolean;
17+
declare let aStringOrNumber: string | number;
18+
declare let aStringOrSomething: string | Something;
19+
declare let someUnion: Something | SomethingElse;
20+
21+
function fn<T extends Table>(o: T) {
22+
aBoolean = o;
23+
aStringOrNumber = o;
24+
aStringOrSomething = o;
25+
someUnion = o;
26+
}
27+
28+
function fn2<T extends TableClass>(o: T) {
29+
aBoolean = o;
30+
aStringOrNumber = o;
31+
aStringOrSomething = o;
32+
someUnion = o;
33+
}
34+
35+
declare const o: Table;
36+
aBoolean = o;
37+
aStringOrNumber = o;
38+
aStringOrSomething = o;
39+
someUnion = o;
40+
41+
42+
//// [typeVariableConstraintedToAliasNotAssignableToUnion.js]
43+
"use strict";
44+
exports.__esModule = true;
45+
function fn(o) {
46+
aBoolean = o;
47+
aStringOrNumber = o;
48+
aStringOrSomething = o;
49+
someUnion = o;
50+
}
51+
function fn2(o) {
52+
aBoolean = o;
53+
aStringOrNumber = o;
54+
aStringOrSomething = o;
55+
someUnion = o;
56+
}
57+
aBoolean = o;
58+
aStringOrNumber = o;
59+
aStringOrSomething = o;
60+
someUnion = o;
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
=== tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts ===
2+
declare class TableClass<S = any> {
3+
>TableClass : Symbol(TableClass, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 0, 0))
4+
>S : Symbol(S, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 0, 25))
5+
6+
_field: S;
7+
>_field : Symbol(TableClass._field, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 0, 35))
8+
>S : Symbol(S, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 0, 25))
9+
}
10+
11+
export type Table = TableClass;
12+
>Table : Symbol(Table, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 2, 1))
13+
>TableClass : Symbol(TableClass, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 0, 0))
14+
15+
interface Something {
16+
>Something : Symbol(Something, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 4, 31))
17+
18+
prop: number;
19+
>prop : Symbol(Something.prop, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 6, 21))
20+
}
21+
22+
interface SomethingElse {
23+
>SomethingElse : Symbol(SomethingElse, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 8, 1))
24+
25+
prop2: string;
26+
>prop2 : Symbol(SomethingElse.prop2, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 10, 25))
27+
}
28+
29+
declare let aBoolean: boolean;
30+
>aBoolean : Symbol(aBoolean, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 14, 11))
31+
32+
declare let aStringOrNumber: string | number;
33+
>aStringOrNumber : Symbol(aStringOrNumber, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 15, 11))
34+
35+
declare let aStringOrSomething: string | Something;
36+
>aStringOrSomething : Symbol(aStringOrSomething, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 16, 11))
37+
>Something : Symbol(Something, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 4, 31))
38+
39+
declare let someUnion: Something | SomethingElse;
40+
>someUnion : Symbol(someUnion, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 17, 11))
41+
>Something : Symbol(Something, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 4, 31))
42+
>SomethingElse : Symbol(SomethingElse, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 8, 1))
43+
44+
function fn<T extends Table>(o: T) {
45+
>fn : Symbol(fn, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 17, 49))
46+
>T : Symbol(T, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 12))
47+
>Table : Symbol(Table, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 2, 1))
48+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 29))
49+
>T : Symbol(T, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 12))
50+
51+
aBoolean = o;
52+
>aBoolean : Symbol(aBoolean, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 14, 11))
53+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 29))
54+
55+
aStringOrNumber = o;
56+
>aStringOrNumber : Symbol(aStringOrNumber, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 15, 11))
57+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 29))
58+
59+
aStringOrSomething = o;
60+
>aStringOrSomething : Symbol(aStringOrSomething, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 16, 11))
61+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 29))
62+
63+
someUnion = o;
64+
>someUnion : Symbol(someUnion, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 17, 11))
65+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 29))
66+
}
67+
68+
function fn2<T extends TableClass>(o: T) {
69+
>fn2 : Symbol(fn2, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 24, 1))
70+
>T : Symbol(T, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 13))
71+
>TableClass : Symbol(TableClass, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 0, 0))
72+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 35))
73+
>T : Symbol(T, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 13))
74+
75+
aBoolean = o;
76+
>aBoolean : Symbol(aBoolean, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 14, 11))
77+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 35))
78+
79+
aStringOrNumber = o;
80+
>aStringOrNumber : Symbol(aStringOrNumber, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 15, 11))
81+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 35))
82+
83+
aStringOrSomething = o;
84+
>aStringOrSomething : Symbol(aStringOrSomething, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 16, 11))
85+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 35))
86+
87+
someUnion = o;
88+
>someUnion : Symbol(someUnion, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 17, 11))
89+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 35))
90+
}
91+
92+
declare const o: Table;
93+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 33, 13))
94+
>Table : Symbol(Table, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 2, 1))
95+
96+
aBoolean = o;
97+
>aBoolean : Symbol(aBoolean, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 14, 11))
98+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 33, 13))
99+
100+
aStringOrNumber = o;
101+
>aStringOrNumber : Symbol(aStringOrNumber, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 15, 11))
102+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 33, 13))
103+
104+
aStringOrSomething = o;
105+
>aStringOrSomething : Symbol(aStringOrSomething, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 16, 11))
106+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 33, 13))
107+
108+
someUnion = o;
109+
>someUnion : Symbol(someUnion, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 17, 11))
110+
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 33, 13))
111+

0 commit comments

Comments
 (0)