diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 36cf9aa947476..0bc9cd76008b5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11778,6 +11778,9 @@ namespace ts { } return Ternary.False; } + if (relation === definitelyAssignableRelation && isGenericMappedType(source)) { + return Ternary.False; + } const sourceIsPrimitive = !!(source.flags & TypeFlags.Primitive); if (relation !== identityRelation) { source = getApparentType(source); diff --git a/tests/baselines/reference/mappedTypeNoTypeNoCrash.types b/tests/baselines/reference/mappedTypeNoTypeNoCrash.types index 1c835498b8155..c3debc7afc279 100644 --- a/tests/baselines/reference/mappedTypeNoTypeNoCrash.types +++ b/tests/baselines/reference/mappedTypeNoTypeNoCrash.types @@ -1,4 +1,4 @@ === tests/cases/compiler/mappedTypeNoTypeNoCrash.ts === type T0 = ({[K in keyof T]}) extends ({[key in K]: T[K]}) ? number : never; ->T0 : number +>T0 : T0 diff --git a/tests/baselines/reference/mappedTypesArraysTuples.js b/tests/baselines/reference/mappedTypesArraysTuples.js index d3d976c04d3e9..5546f5201df00 100644 --- a/tests/baselines/reference/mappedTypesArraysTuples.js +++ b/tests/baselines/reference/mappedTypesArraysTuples.js @@ -83,6 +83,14 @@ declare function mapArray(arr: T): Mapped; function acceptMappedArray(arr: T) { acceptArray(mapArray(arr)); } + +// Repro from #26163 + +type Unconstrained = ElementType>; +type T1 = Unconstrained<[string, number, boolean]>; // string | number | boolean + +type Constrained = ElementType>; +type T2 = Constrained<[string, number, boolean]>; // string | number | boolean //// [mappedTypesArraysTuples.js] @@ -182,3 +190,7 @@ declare type R2 = ElementType>; declare function acceptArray(arr: any[]): void; declare function mapArray(arr: T): Mapped; declare function acceptMappedArray(arr: T): void; +declare type Unconstrained = ElementType>; +declare type T1 = Unconstrained<[string, number, boolean]>; +declare type Constrained = ElementType>; +declare type T2 = Constrained<[string, number, boolean]>; diff --git a/tests/baselines/reference/mappedTypesArraysTuples.symbols b/tests/baselines/reference/mappedTypesArraysTuples.symbols index 1815b354b6c9b..ffc7fe19e3fdf 100644 --- a/tests/baselines/reference/mappedTypesArraysTuples.symbols +++ b/tests/baselines/reference/mappedTypesArraysTuples.symbols @@ -328,3 +328,27 @@ function acceptMappedArray(arr: T) { >arr : Symbol(arr, Decl(mappedTypesArraysTuples.ts, 81, 44)) } +// Repro from #26163 + +type Unconstrained = ElementType>; +>Unconstrained : Symbol(Unconstrained, Decl(mappedTypesArraysTuples.ts, 83, 1)) +>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 87, 19)) +>ElementType : Symbol(ElementType, Decl(mappedTypesArraysTuples.ts, 66, 1)) +>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 70, 59)) +>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 87, 19)) + +type T1 = Unconstrained<[string, number, boolean]>; // string | number | boolean +>T1 : Symbol(T1, Decl(mappedTypesArraysTuples.ts, 87, 47)) +>Unconstrained : Symbol(Unconstrained, Decl(mappedTypesArraysTuples.ts, 83, 1)) + +type Constrained = ElementType>; +>Constrained : Symbol(Constrained, Decl(mappedTypesArraysTuples.ts, 88, 51)) +>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 90, 17)) +>ElementType : Symbol(ElementType, Decl(mappedTypesArraysTuples.ts, 66, 1)) +>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 70, 59)) +>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 90, 17)) + +type T2 = Constrained<[string, number, boolean]>; // string | number | boolean +>T2 : Symbol(T2, Decl(mappedTypesArraysTuples.ts, 90, 59)) +>Constrained : Symbol(Constrained, Decl(mappedTypesArraysTuples.ts, 88, 51)) + diff --git a/tests/baselines/reference/mappedTypesArraysTuples.types b/tests/baselines/reference/mappedTypesArraysTuples.types index 42ab457b783ce..df99246e9bd27 100644 --- a/tests/baselines/reference/mappedTypesArraysTuples.types +++ b/tests/baselines/reference/mappedTypesArraysTuples.types @@ -241,3 +241,17 @@ function acceptMappedArray(arr: T) { >arr : T } +// Repro from #26163 + +type Unconstrained = ElementType>; +>Unconstrained : ElementType> + +type T1 = Unconstrained<[string, number, boolean]>; // string | number | boolean +>T1 : string | number | boolean + +type Constrained = ElementType>; +>Constrained : ElementType> + +type T2 = Constrained<[string, number, boolean]>; // string | number | boolean +>T2 : string | number | boolean + diff --git a/tests/cases/conformance/types/mapped/mappedTypesArraysTuples.ts b/tests/cases/conformance/types/mapped/mappedTypesArraysTuples.ts index c936a86c897d0..5d8fbc4b37978 100644 --- a/tests/cases/conformance/types/mapped/mappedTypesArraysTuples.ts +++ b/tests/cases/conformance/types/mapped/mappedTypesArraysTuples.ts @@ -85,3 +85,11 @@ declare function mapArray(arr: T): Mapped; function acceptMappedArray(arr: T) { acceptArray(mapArray(arr)); } + +// Repro from #26163 + +type Unconstrained = ElementType>; +type T1 = Unconstrained<[string, number, boolean]>; // string | number | boolean + +type Constrained = ElementType>; +type T2 = Constrained<[string, number, boolean]>; // string | number | boolean