mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-23 07:07:09 -05:00
Propagate wildcard types in non-homomorphic mapped types (#41622)
* Propagate wildcard types in non-homomorphic mapped types * Add regression test * Accept new baselines * Accept new baselines
This commit is contained in:
@@ -15276,7 +15276,9 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
}
|
||||
return instantiateAnonymousType(type, mapper);
|
||||
// If the constraint type of the instantiation is the wildcard type, return the wildcard type.
|
||||
const result = <MappedType>instantiateAnonymousType(type, mapper);
|
||||
return getConstraintTypeFromMappedType(result) === wildcardType ? wildcardType : result;
|
||||
}
|
||||
|
||||
function getModifiedReadonlyState(state: boolean, modifiers: MappedTypeModifiers) {
|
||||
|
||||
@@ -326,4 +326,10 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2
|
||||
declare function gg<T>(f: (x: Foo3<T>) => void): void;
|
||||
type Foo3<T> = T extends number ? { n: T } : { x: T };
|
||||
gg(ff);
|
||||
|
||||
// Repro from #41613
|
||||
|
||||
type Wat<K extends string> = { x: { y: 0, z: 1 } } extends { x: { [P in K]: 0 } } ? true : false;
|
||||
|
||||
type Huh = Wat<"y">; // true
|
||||
|
||||
@@ -237,6 +237,12 @@ declare function ff(x: Foo3<string>): void;
|
||||
declare function gg<T>(f: (x: Foo3<T>) => void): void;
|
||||
type Foo3<T> = T extends number ? { n: T } : { x: T };
|
||||
gg(ff);
|
||||
|
||||
// Repro from #41613
|
||||
|
||||
type Wat<K extends string> = { x: { y: 0, z: 1 } } extends { x: { [P in K]: 0 } } ? true : false;
|
||||
|
||||
type Huh = Wat<"y">; // true
|
||||
|
||||
|
||||
//// [conditionalTypes2.js]
|
||||
@@ -477,3 +483,14 @@ declare type Foo3<T> = T extends number ? {
|
||||
} : {
|
||||
x: T;
|
||||
};
|
||||
declare type Wat<K extends string> = {
|
||||
x: {
|
||||
y: 0;
|
||||
z: 1;
|
||||
};
|
||||
} extends {
|
||||
x: {
|
||||
[P in K]: 0;
|
||||
};
|
||||
} ? true : false;
|
||||
declare type Huh = Wat<"y">;
|
||||
|
||||
@@ -841,3 +841,19 @@ gg(ff);
|
||||
>gg : Symbol(gg, Decl(conditionalTypes2.ts, 234, 43))
|
||||
>ff : Symbol(ff, Decl(conditionalTypes2.ts, 230, 2))
|
||||
|
||||
// Repro from #41613
|
||||
|
||||
type Wat<K extends string> = { x: { y: 0, z: 1 } } extends { x: { [P in K]: 0 } } ? true : false;
|
||||
>Wat : Symbol(Wat, Decl(conditionalTypes2.ts, 237, 7))
|
||||
>K : Symbol(K, Decl(conditionalTypes2.ts, 241, 9))
|
||||
>x : Symbol(x, Decl(conditionalTypes2.ts, 241, 30))
|
||||
>y : Symbol(y, Decl(conditionalTypes2.ts, 241, 35))
|
||||
>z : Symbol(z, Decl(conditionalTypes2.ts, 241, 41))
|
||||
>x : Symbol(x, Decl(conditionalTypes2.ts, 241, 60))
|
||||
>P : Symbol(P, Decl(conditionalTypes2.ts, 241, 67))
|
||||
>K : Symbol(K, Decl(conditionalTypes2.ts, 241, 9))
|
||||
|
||||
type Huh = Wat<"y">; // true
|
||||
>Huh : Symbol(Huh, Decl(conditionalTypes2.ts, 241, 97))
|
||||
>Wat : Symbol(Wat, Decl(conditionalTypes2.ts, 237, 7))
|
||||
|
||||
|
||||
@@ -527,3 +527,17 @@ gg(ff);
|
||||
>gg : <T>(f: (x: Foo3<T>) => void) => void
|
||||
>ff : (x: { x: string; }) => void
|
||||
|
||||
// Repro from #41613
|
||||
|
||||
type Wat<K extends string> = { x: { y: 0, z: 1 } } extends { x: { [P in K]: 0 } } ? true : false;
|
||||
>Wat : Wat<K>
|
||||
>x : { y: 0; z: 1; }
|
||||
>y : 0
|
||||
>z : 1
|
||||
>x : { [P in K]: 0; }
|
||||
>true : true
|
||||
>false : false
|
||||
|
||||
type Huh = Wat<"y">; // true
|
||||
>Huh : true
|
||||
|
||||
|
||||
@@ -6,10 +6,11 @@ tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(11,6): error TS2456
|
||||
tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(12,11): error TS2313: Type parameter 'K' has a circular constraint.
|
||||
tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(20,19): error TS2589: Type instantiation is excessively deep and possibly infinite.
|
||||
tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(66,25): error TS2313: Type parameter 'P' has a circular constraint.
|
||||
tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(79,1): error TS2615: Type of property '"each"' circularly references itself in mapped type '{ type: never; minimum_count: never; maximum_count: never; collapsable?: never; each: never; }'.
|
||||
tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(73,5): error TS2502: '"each"' is referenced directly or indirectly in its own type annotation.
|
||||
tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(73,13): error TS2615: Type of property '"each"' circularly references itself in mapped type '{ [P in keyof ListWidget]: undefined extends ListWidget[P] ? never : P; }'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts (9 errors) ====
|
||||
==== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts (10 errors) ====
|
||||
// Recursive mapped types simply appear empty
|
||||
|
||||
type Recurse = {
|
||||
@@ -93,7 +94,7 @@ tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(79,1): error TS2615
|
||||
type Child<T> = { [P in NonOptionalKeys<T>]: T[P] }
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2313: Type parameter 'P' has a circular constraint.
|
||||
!!! related TS2751 tests/cases/conformance/types/mapped/recursiveMappedTypes.ts:79:1: Circularity originates in type at this location.
|
||||
!!! related TS2751 tests/cases/conformance/types/mapped/recursiveMappedTypes.ts:73:13: Circularity originates in type at this location.
|
||||
|
||||
export interface ListWidget {
|
||||
"type": "list",
|
||||
@@ -101,12 +102,14 @@ tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(79,1): error TS2615
|
||||
"maximum_count": number,
|
||||
"collapsable"?: boolean, //default to false, means all expanded
|
||||
"each": Child<ListWidget>;
|
||||
~~~~~~
|
||||
!!! error TS2502: '"each"' is referenced directly or indirectly in its own type annotation.
|
||||
~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2615: Type of property '"each"' circularly references itself in mapped type '{ [P in keyof ListWidget]: undefined extends ListWidget[P] ? never : P; }'.
|
||||
}
|
||||
|
||||
type ListChild = Child<ListWidget>
|
||||
|
||||
declare let x: ListChild;
|
||||
x.type;
|
||||
~~~~~~
|
||||
!!! error TS2615: Type of property '"each"' circularly references itself in mapped type '{ type: never; minimum_count: never; maximum_count: never; collapsable?: never; each: never; }'.
|
||||
|
||||
@@ -119,7 +119,7 @@ export interface ListWidget {
|
||||
>"collapsable" : boolean
|
||||
|
||||
"each": Child<ListWidget>;
|
||||
>"each" : Child<ListWidget>
|
||||
>"each" : any
|
||||
}
|
||||
|
||||
type ListChild = Child<ListWidget>
|
||||
|
||||
@@ -239,3 +239,9 @@ declare function ff(x: Foo3<string>): void;
|
||||
declare function gg<T>(f: (x: Foo3<T>) => void): void;
|
||||
type Foo3<T> = T extends number ? { n: T } : { x: T };
|
||||
gg(ff);
|
||||
|
||||
// Repro from #41613
|
||||
|
||||
type Wat<K extends string> = { x: { y: 0, z: 1 } } extends { x: { [P in K]: 0 } } ? true : false;
|
||||
|
||||
type Huh = Wat<"y">; // true
|
||||
|
||||
Reference in New Issue
Block a user