Normalize effective constraint intersection before checking if source is a part of it (#49956)

This commit is contained in:
Jake Bailey 2022-07-27 10:06:01 -07:00 committed by GitHub
parent adfb20fbeb
commit 8d0c72d5e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 541 additions and 1 deletions

View File

@ -12124,7 +12124,8 @@ namespace ts {
}
}
}
return getIntersectionType(constraints);
// The source types were normalized; ensure the result is normalized too.
return getNormalizedType(getIntersectionType(constraints), /*writing*/ false);
}
return undefined;
}

View File

@ -0,0 +1,29 @@
//// [instanceofTypeAliasToGenericClass.ts]
declare class TableClass<S = any> {
_field: S;
}
export type Table = TableClass;
function fn<T extends Table>(o: T) {
return o instanceof TableClass;
}
function fn2<T extends TableClass>(o: T) {
return o instanceof TableClass;
}
declare const o: Table;
o instanceof TableClass;
//// [instanceofTypeAliasToGenericClass.js]
"use strict";
exports.__esModule = true;
function fn(o) {
return o instanceof TableClass;
}
function fn2(o) {
return o instanceof TableClass;
}
o instanceof TableClass;

View File

@ -0,0 +1,46 @@
=== tests/cases/compiler/instanceofTypeAliasToGenericClass.ts ===
declare class TableClass<S = any> {
>TableClass : Symbol(TableClass, Decl(instanceofTypeAliasToGenericClass.ts, 0, 0))
>S : Symbol(S, Decl(instanceofTypeAliasToGenericClass.ts, 0, 25))
_field: S;
>_field : Symbol(TableClass._field, Decl(instanceofTypeAliasToGenericClass.ts, 0, 35))
>S : Symbol(S, Decl(instanceofTypeAliasToGenericClass.ts, 0, 25))
}
export type Table = TableClass;
>Table : Symbol(Table, Decl(instanceofTypeAliasToGenericClass.ts, 2, 1))
>TableClass : Symbol(TableClass, Decl(instanceofTypeAliasToGenericClass.ts, 0, 0))
function fn<T extends Table>(o: T) {
>fn : Symbol(fn, Decl(instanceofTypeAliasToGenericClass.ts, 4, 31))
>T : Symbol(T, Decl(instanceofTypeAliasToGenericClass.ts, 6, 12))
>Table : Symbol(Table, Decl(instanceofTypeAliasToGenericClass.ts, 2, 1))
>o : Symbol(o, Decl(instanceofTypeAliasToGenericClass.ts, 6, 29))
>T : Symbol(T, Decl(instanceofTypeAliasToGenericClass.ts, 6, 12))
return o instanceof TableClass;
>o : Symbol(o, Decl(instanceofTypeAliasToGenericClass.ts, 6, 29))
>TableClass : Symbol(TableClass, Decl(instanceofTypeAliasToGenericClass.ts, 0, 0))
}
function fn2<T extends TableClass>(o: T) {
>fn2 : Symbol(fn2, Decl(instanceofTypeAliasToGenericClass.ts, 8, 1))
>T : Symbol(T, Decl(instanceofTypeAliasToGenericClass.ts, 10, 13))
>TableClass : Symbol(TableClass, Decl(instanceofTypeAliasToGenericClass.ts, 0, 0))
>o : Symbol(o, Decl(instanceofTypeAliasToGenericClass.ts, 10, 35))
>T : Symbol(T, Decl(instanceofTypeAliasToGenericClass.ts, 10, 13))
return o instanceof TableClass;
>o : Symbol(o, Decl(instanceofTypeAliasToGenericClass.ts, 10, 35))
>TableClass : Symbol(TableClass, Decl(instanceofTypeAliasToGenericClass.ts, 0, 0))
}
declare const o: Table;
>o : Symbol(o, Decl(instanceofTypeAliasToGenericClass.ts, 14, 13))
>Table : Symbol(Table, Decl(instanceofTypeAliasToGenericClass.ts, 2, 1))
o instanceof TableClass;
>o : Symbol(o, Decl(instanceofTypeAliasToGenericClass.ts, 14, 13))
>TableClass : Symbol(TableClass, Decl(instanceofTypeAliasToGenericClass.ts, 0, 0))

View File

@ -0,0 +1,39 @@
=== tests/cases/compiler/instanceofTypeAliasToGenericClass.ts ===
declare class TableClass<S = any> {
>TableClass : TableClass<S>
_field: S;
>_field : S
}
export type Table = TableClass;
>Table : TableClass<any>
function fn<T extends Table>(o: T) {
>fn : <T extends Table>(o: T) => boolean
>o : T
return o instanceof TableClass;
>o instanceof TableClass : boolean
>o : T
>TableClass : typeof TableClass
}
function fn2<T extends TableClass>(o: T) {
>fn2 : <T extends TableClass<any>>(o: T) => boolean
>o : T
return o instanceof TableClass;
>o instanceof TableClass : boolean
>o : T
>TableClass : typeof TableClass
}
declare const o: Table;
>o : Table
o instanceof TableClass;
>o instanceof TableClass : boolean
>o : Table
>TableClass : typeof TableClass

View File

@ -0,0 +1,94 @@
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(21,5): error TS2322: Type 'T' is not assignable to type 'boolean'.
Type 'TableClass<any>' is not assignable to type 'boolean'.
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(22,5): error TS2322: Type 'T' is not assignable to type 'string | number'.
Type 'TableClass<any>' is not assignable to type 'string | number'.
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(23,5): error TS2322: Type 'T' is not assignable to type 'string | Something'.
Type 'TableClass<any>' is not assignable to type 'string | Something'.
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(24,5): error TS2322: Type 'T' is not assignable to type 'Something | SomethingElse'.
Type 'TableClass<any>' is not assignable to type 'Something | SomethingElse'.
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(28,5): error TS2322: Type 'T' is not assignable to type 'boolean'.
Type 'TableClass<any>' is not assignable to type 'boolean'.
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(29,5): error TS2322: Type 'T' is not assignable to type 'string | number'.
Type 'TableClass<any>' is not assignable to type 'string | number'.
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(30,5): error TS2322: Type 'T' is not assignable to type 'string | Something'.
Type 'TableClass<any>' is not assignable to type 'string | Something'.
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(31,5): error TS2322: Type 'T' is not assignable to type 'Something | SomethingElse'.
Type 'TableClass<any>' is not assignable to type 'Something | SomethingElse'.
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(35,1): error TS2322: Type 'Table' is not assignable to type 'boolean'.
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(36,1): error TS2322: Type 'Table' is not assignable to type 'string | number'.
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(37,1): error TS2322: Type 'Table' is not assignable to type 'string | Something'.
tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts(38,1): error TS2322: Type 'Table' is not assignable to type 'Something | SomethingElse'.
==== tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts (12 errors) ====
declare class TableClass<S = any> {
_field: S;
}
export type Table = TableClass;
interface Something {
prop: number;
}
interface SomethingElse {
prop2: string;
}
declare let aBoolean: boolean;
declare let aStringOrNumber: string | number;
declare let aStringOrSomething: string | Something;
declare let someUnion: Something | SomethingElse;
function fn<T extends Table>(o: T) {
aBoolean = o;
~~~~~~~~
!!! error TS2322: Type 'T' is not assignable to type 'boolean'.
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'boolean'.
aStringOrNumber = o;
~~~~~~~~~~~~~~~
!!! error TS2322: Type 'T' is not assignable to type 'string | number'.
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'string | number'.
aStringOrSomething = o;
~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type 'T' is not assignable to type 'string | Something'.
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'string | Something'.
someUnion = o;
~~~~~~~~~
!!! error TS2322: Type 'T' is not assignable to type 'Something | SomethingElse'.
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'Something | SomethingElse'.
}
function fn2<T extends TableClass>(o: T) {
aBoolean = o;
~~~~~~~~
!!! error TS2322: Type 'T' is not assignable to type 'boolean'.
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'boolean'.
aStringOrNumber = o;
~~~~~~~~~~~~~~~
!!! error TS2322: Type 'T' is not assignable to type 'string | number'.
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'string | number'.
aStringOrSomething = o;
~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type 'T' is not assignable to type 'string | Something'.
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'string | Something'.
someUnion = o;
~~~~~~~~~
!!! error TS2322: Type 'T' is not assignable to type 'Something | SomethingElse'.
!!! error TS2322: Type 'TableClass<any>' is not assignable to type 'Something | SomethingElse'.
}
declare const o: Table;
aBoolean = o;
~~~~~~~~
!!! error TS2322: Type 'Table' is not assignable to type 'boolean'.
aStringOrNumber = o;
~~~~~~~~~~~~~~~
!!! error TS2322: Type 'Table' is not assignable to type 'string | number'.
aStringOrSomething = o;
~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type 'Table' is not assignable to type 'string | Something'.
someUnion = o;
~~~~~~~~~
!!! error TS2322: Type 'Table' is not assignable to type 'Something | SomethingElse'.

View File

@ -0,0 +1,60 @@
//// [typeVariableConstraintedToAliasNotAssignableToUnion.ts]
declare class TableClass<S = any> {
_field: S;
}
export type Table = TableClass;
interface Something {
prop: number;
}
interface SomethingElse {
prop2: string;
}
declare let aBoolean: boolean;
declare let aStringOrNumber: string | number;
declare let aStringOrSomething: string | Something;
declare let someUnion: Something | SomethingElse;
function fn<T extends Table>(o: T) {
aBoolean = o;
aStringOrNumber = o;
aStringOrSomething = o;
someUnion = o;
}
function fn2<T extends TableClass>(o: T) {
aBoolean = o;
aStringOrNumber = o;
aStringOrSomething = o;
someUnion = o;
}
declare const o: Table;
aBoolean = o;
aStringOrNumber = o;
aStringOrSomething = o;
someUnion = o;
//// [typeVariableConstraintedToAliasNotAssignableToUnion.js]
"use strict";
exports.__esModule = true;
function fn(o) {
aBoolean = o;
aStringOrNumber = o;
aStringOrSomething = o;
someUnion = o;
}
function fn2(o) {
aBoolean = o;
aStringOrNumber = o;
aStringOrSomething = o;
someUnion = o;
}
aBoolean = o;
aStringOrNumber = o;
aStringOrSomething = o;
someUnion = o;

View File

@ -0,0 +1,111 @@
=== tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts ===
declare class TableClass<S = any> {
>TableClass : Symbol(TableClass, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 0, 0))
>S : Symbol(S, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 0, 25))
_field: S;
>_field : Symbol(TableClass._field, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 0, 35))
>S : Symbol(S, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 0, 25))
}
export type Table = TableClass;
>Table : Symbol(Table, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 2, 1))
>TableClass : Symbol(TableClass, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 0, 0))
interface Something {
>Something : Symbol(Something, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 4, 31))
prop: number;
>prop : Symbol(Something.prop, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 6, 21))
}
interface SomethingElse {
>SomethingElse : Symbol(SomethingElse, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 8, 1))
prop2: string;
>prop2 : Symbol(SomethingElse.prop2, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 10, 25))
}
declare let aBoolean: boolean;
>aBoolean : Symbol(aBoolean, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 14, 11))
declare let aStringOrNumber: string | number;
>aStringOrNumber : Symbol(aStringOrNumber, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 15, 11))
declare let aStringOrSomething: string | Something;
>aStringOrSomething : Symbol(aStringOrSomething, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 16, 11))
>Something : Symbol(Something, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 4, 31))
declare let someUnion: Something | SomethingElse;
>someUnion : Symbol(someUnion, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 17, 11))
>Something : Symbol(Something, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 4, 31))
>SomethingElse : Symbol(SomethingElse, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 8, 1))
function fn<T extends Table>(o: T) {
>fn : Symbol(fn, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 17, 49))
>T : Symbol(T, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 12))
>Table : Symbol(Table, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 2, 1))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 29))
>T : Symbol(T, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 12))
aBoolean = o;
>aBoolean : Symbol(aBoolean, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 14, 11))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 29))
aStringOrNumber = o;
>aStringOrNumber : Symbol(aStringOrNumber, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 15, 11))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 29))
aStringOrSomething = o;
>aStringOrSomething : Symbol(aStringOrSomething, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 16, 11))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 29))
someUnion = o;
>someUnion : Symbol(someUnion, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 17, 11))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 19, 29))
}
function fn2<T extends TableClass>(o: T) {
>fn2 : Symbol(fn2, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 24, 1))
>T : Symbol(T, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 13))
>TableClass : Symbol(TableClass, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 0, 0))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 35))
>T : Symbol(T, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 13))
aBoolean = o;
>aBoolean : Symbol(aBoolean, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 14, 11))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 35))
aStringOrNumber = o;
>aStringOrNumber : Symbol(aStringOrNumber, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 15, 11))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 35))
aStringOrSomething = o;
>aStringOrSomething : Symbol(aStringOrSomething, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 16, 11))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 35))
someUnion = o;
>someUnion : Symbol(someUnion, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 17, 11))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 26, 35))
}
declare const o: Table;
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 33, 13))
>Table : Symbol(Table, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 2, 1))
aBoolean = o;
>aBoolean : Symbol(aBoolean, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 14, 11))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 33, 13))
aStringOrNumber = o;
>aStringOrNumber : Symbol(aStringOrNumber, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 15, 11))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 33, 13))
aStringOrSomething = o;
>aStringOrSomething : Symbol(aStringOrSomething, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 16, 11))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 33, 13))
someUnion = o;
>someUnion : Symbol(someUnion, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 17, 11))
>o : Symbol(o, Decl(typeVariableConstraintedToAliasNotAssignableToUnion.ts, 33, 13))

View File

@ -0,0 +1,106 @@
=== tests/cases/compiler/typeVariableConstraintedToAliasNotAssignableToUnion.ts ===
declare class TableClass<S = any> {
>TableClass : TableClass<S>
_field: S;
>_field : S
}
export type Table = TableClass;
>Table : TableClass<any>
interface Something {
prop: number;
>prop : number
}
interface SomethingElse {
prop2: string;
>prop2 : string
}
declare let aBoolean: boolean;
>aBoolean : boolean
declare let aStringOrNumber: string | number;
>aStringOrNumber : string | number
declare let aStringOrSomething: string | Something;
>aStringOrSomething : string | Something
declare let someUnion: Something | SomethingElse;
>someUnion : Something | SomethingElse
function fn<T extends Table>(o: T) {
>fn : <T extends Table>(o: T) => void
>o : T
aBoolean = o;
>aBoolean = o : T
>aBoolean : boolean
>o : T
aStringOrNumber = o;
>aStringOrNumber = o : T
>aStringOrNumber : string | number
>o : T
aStringOrSomething = o;
>aStringOrSomething = o : T
>aStringOrSomething : string | Something
>o : T
someUnion = o;
>someUnion = o : T
>someUnion : Something | SomethingElse
>o : T
}
function fn2<T extends TableClass>(o: T) {
>fn2 : <T extends TableClass<any>>(o: T) => void
>o : T
aBoolean = o;
>aBoolean = o : T
>aBoolean : boolean
>o : T
aStringOrNumber = o;
>aStringOrNumber = o : T
>aStringOrNumber : string | number
>o : T
aStringOrSomething = o;
>aStringOrSomething = o : T
>aStringOrSomething : string | Something
>o : T
someUnion = o;
>someUnion = o : T
>someUnion : Something | SomethingElse
>o : T
}
declare const o: Table;
>o : Table
aBoolean = o;
>aBoolean = o : Table
>aBoolean : boolean
>o : Table
aStringOrNumber = o;
>aStringOrNumber = o : Table
>aStringOrNumber : string | number
>o : Table
aStringOrSomething = o;
>aStringOrSomething = o : Table
>aStringOrSomething : string | Something
>o : Table
someUnion = o;
>someUnion = o : Table
>someUnion : Something | SomethingElse
>o : Table

View File

@ -0,0 +1,16 @@
declare class TableClass<S = any> {
_field: S;
}
export type Table = TableClass;
function fn<T extends Table>(o: T) {
return o instanceof TableClass;
}
function fn2<T extends TableClass>(o: T) {
return o instanceof TableClass;
}
declare const o: Table;
o instanceof TableClass;

View File

@ -0,0 +1,38 @@
declare class TableClass<S = any> {
_field: S;
}
export type Table = TableClass;
interface Something {
prop: number;
}
interface SomethingElse {
prop2: string;
}
declare let aBoolean: boolean;
declare let aStringOrNumber: string | number;
declare let aStringOrSomething: string | Something;
declare let someUnion: Something | SomethingElse;
function fn<T extends Table>(o: T) {
aBoolean = o;
aStringOrNumber = o;
aStringOrSomething = o;
someUnion = o;
}
function fn2<T extends TableClass>(o: T) {
aBoolean = o;
aStringOrNumber = o;
aStringOrSomething = o;
someUnion = o;
}
declare const o: Table;
aBoolean = o;
aStringOrNumber = o;
aStringOrSomething = o;
someUnion = o;