mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-11 20:37:46 -05:00
Merge pull request #21696 from Microsoft/fixMappedTypeWithSubstitution
Handle all instantiable non-primitive types in mapped types
This commit is contained in:
@@ -8781,7 +8781,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isMappableType(type: Type) {
|
||||
return type.flags & (TypeFlags.Any | TypeFlags.TypeParameter | TypeFlags.Object | TypeFlags.Intersection | TypeFlags.IndexedAccess);
|
||||
return type.flags & (TypeFlags.Any | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection);
|
||||
}
|
||||
|
||||
function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper): AnonymousType {
|
||||
|
||||
@@ -108,4 +108,36 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(72,43): error TS4081: E
|
||||
!!! error TS2304: Cannot find name 'U'.
|
||||
~
|
||||
!!! error TS4081: Exported type alias 'T62' has or is using private name 'U'.
|
||||
|
||||
// Example from #21496
|
||||
|
||||
type JsonifiedObject<T extends object> = { [K in keyof T]: Jsonified<T[K]> };
|
||||
|
||||
type Jsonified<T> =
|
||||
T extends string | number | boolean | null ? T
|
||||
: T extends undefined | Function ? never // undefined and functions are removed
|
||||
: T extends { toJSON(): infer R } ? R // toJSON is called if it exists (e.g. Date)
|
||||
: T extends object ? JsonifiedObject<T>
|
||||
: "what is this";
|
||||
|
||||
type Example = {
|
||||
str: "literalstring",
|
||||
fn: () => void,
|
||||
date: Date,
|
||||
customClass: MyClass,
|
||||
obj: {
|
||||
prop: "property",
|
||||
clz: MyClass,
|
||||
nested: { attr: Date }
|
||||
},
|
||||
}
|
||||
|
||||
declare class MyClass {
|
||||
toJSON(): "correct";
|
||||
}
|
||||
|
||||
type JsonifiedExample = Jsonified<Example>;
|
||||
declare let ex: JsonifiedExample;
|
||||
const z1: "correct" = ex.customClass;
|
||||
const z2: string = ex.obj.nested.attr;
|
||||
|
||||
@@ -71,6 +71,38 @@ type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number
|
||||
type T60 = infer U; // Error
|
||||
type T61<T> = infer A extends infer B ? infer C : infer D; // Error
|
||||
type T62<T> = U extends (infer U)[] ? U : U; // Error
|
||||
|
||||
// Example from #21496
|
||||
|
||||
type JsonifiedObject<T extends object> = { [K in keyof T]: Jsonified<T[K]> };
|
||||
|
||||
type Jsonified<T> =
|
||||
T extends string | number | boolean | null ? T
|
||||
: T extends undefined | Function ? never // undefined and functions are removed
|
||||
: T extends { toJSON(): infer R } ? R // toJSON is called if it exists (e.g. Date)
|
||||
: T extends object ? JsonifiedObject<T>
|
||||
: "what is this";
|
||||
|
||||
type Example = {
|
||||
str: "literalstring",
|
||||
fn: () => void,
|
||||
date: Date,
|
||||
customClass: MyClass,
|
||||
obj: {
|
||||
prop: "property",
|
||||
clz: MyClass,
|
||||
nested: { attr: Date }
|
||||
},
|
||||
}
|
||||
|
||||
declare class MyClass {
|
||||
toJSON(): "correct";
|
||||
}
|
||||
|
||||
type JsonifiedExample = Jsonified<Example>;
|
||||
declare let ex: JsonifiedExample;
|
||||
const z1: "correct" = ex.customClass;
|
||||
const z2: string = ex.obj.nested.attr;
|
||||
|
||||
|
||||
//// [inferTypes1.js]
|
||||
@@ -85,3 +117,5 @@ var C = /** @class */ (function () {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
var z1 = ex.customClass;
|
||||
var z2 = ex.obj.nested.attr;
|
||||
|
||||
@@ -315,3 +315,106 @@ type T62<T> = U extends (infer U)[] ? U : U; // Error
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 71, 30))
|
||||
>U : Symbol(U, Decl(inferTypes1.ts, 71, 30))
|
||||
|
||||
// Example from #21496
|
||||
|
||||
type JsonifiedObject<T extends object> = { [K in keyof T]: Jsonified<T[K]> };
|
||||
>JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 71, 44))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 75, 21))
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 75, 44))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 75, 21))
|
||||
>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 75, 77))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 75, 21))
|
||||
>K : Symbol(K, Decl(inferTypes1.ts, 75, 44))
|
||||
|
||||
type Jsonified<T> =
|
||||
>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 75, 77))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 77, 15))
|
||||
|
||||
T extends string | number | boolean | null ? T
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 77, 15))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 77, 15))
|
||||
|
||||
: T extends undefined | Function ? never // undefined and functions are removed
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 77, 15))
|
||||
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
: T extends { toJSON(): infer R } ? R // toJSON is called if it exists (e.g. Date)
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 77, 15))
|
||||
>toJSON : Symbol(toJSON, Decl(inferTypes1.ts, 80, 17))
|
||||
>R : Symbol(R, Decl(inferTypes1.ts, 80, 33))
|
||||
>R : Symbol(R, Decl(inferTypes1.ts, 80, 33))
|
||||
|
||||
: T extends object ? JsonifiedObject<T>
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 77, 15))
|
||||
>JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 71, 44))
|
||||
>T : Symbol(T, Decl(inferTypes1.ts, 77, 15))
|
||||
|
||||
: "what is this";
|
||||
|
||||
type Example = {
|
||||
>Example : Symbol(Example, Decl(inferTypes1.ts, 82, 21))
|
||||
|
||||
str: "literalstring",
|
||||
>str : Symbol(str, Decl(inferTypes1.ts, 84, 16))
|
||||
|
||||
fn: () => void,
|
||||
>fn : Symbol(fn, Decl(inferTypes1.ts, 85, 25))
|
||||
|
||||
date: Date,
|
||||
>date : Symbol(date, Decl(inferTypes1.ts, 86, 19))
|
||||
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
customClass: MyClass,
|
||||
>customClass : Symbol(customClass, Decl(inferTypes1.ts, 87, 15))
|
||||
>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 94, 1))
|
||||
|
||||
obj: {
|
||||
>obj : Symbol(obj, Decl(inferTypes1.ts, 88, 25))
|
||||
|
||||
prop: "property",
|
||||
>prop : Symbol(prop, Decl(inferTypes1.ts, 89, 10))
|
||||
|
||||
clz: MyClass,
|
||||
>clz : Symbol(clz, Decl(inferTypes1.ts, 90, 25))
|
||||
>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 94, 1))
|
||||
|
||||
nested: { attr: Date }
|
||||
>nested : Symbol(nested, Decl(inferTypes1.ts, 91, 21))
|
||||
>attr : Symbol(attr, Decl(inferTypes1.ts, 92, 17))
|
||||
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
declare class MyClass {
|
||||
>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 94, 1))
|
||||
|
||||
toJSON(): "correct";
|
||||
>toJSON : Symbol(MyClass.toJSON, Decl(inferTypes1.ts, 96, 23))
|
||||
}
|
||||
|
||||
type JsonifiedExample = Jsonified<Example>;
|
||||
>JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 98, 1))
|
||||
>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 75, 77))
|
||||
>Example : Symbol(Example, Decl(inferTypes1.ts, 82, 21))
|
||||
|
||||
declare let ex: JsonifiedExample;
|
||||
>ex : Symbol(ex, Decl(inferTypes1.ts, 101, 11))
|
||||
>JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 98, 1))
|
||||
|
||||
const z1: "correct" = ex.customClass;
|
||||
>z1 : Symbol(z1, Decl(inferTypes1.ts, 102, 5))
|
||||
>ex.customClass : Symbol(customClass, Decl(inferTypes1.ts, 87, 15))
|
||||
>ex : Symbol(ex, Decl(inferTypes1.ts, 101, 11))
|
||||
>customClass : Symbol(customClass, Decl(inferTypes1.ts, 87, 15))
|
||||
|
||||
const z2: string = ex.obj.nested.attr;
|
||||
>z2 : Symbol(z2, Decl(inferTypes1.ts, 103, 5))
|
||||
>ex.obj.nested.attr : Symbol(attr, Decl(inferTypes1.ts, 92, 17))
|
||||
>ex.obj.nested : Symbol(nested, Decl(inferTypes1.ts, 91, 21))
|
||||
>ex.obj : Symbol(obj, Decl(inferTypes1.ts, 88, 25))
|
||||
>ex : Symbol(ex, Decl(inferTypes1.ts, 101, 11))
|
||||
>obj : Symbol(obj, Decl(inferTypes1.ts, 88, 25))
|
||||
>nested : Symbol(nested, Decl(inferTypes1.ts, 91, 21))
|
||||
>attr : Symbol(attr, Decl(inferTypes1.ts, 92, 17))
|
||||
|
||||
|
||||
@@ -321,3 +321,107 @@ type T62<T> = U extends (infer U)[] ? U : U; // Error
|
||||
>U : U
|
||||
>U : No type information available!
|
||||
|
||||
// Example from #21496
|
||||
|
||||
type JsonifiedObject<T extends object> = { [K in keyof T]: Jsonified<T[K]> };
|
||||
>JsonifiedObject : JsonifiedObject<T>
|
||||
>T : T
|
||||
>K : K
|
||||
>T : T
|
||||
>Jsonified : Jsonified<T>
|
||||
>T : T
|
||||
>K : K
|
||||
|
||||
type Jsonified<T> =
|
||||
>Jsonified : Jsonified<T>
|
||||
>T : T
|
||||
|
||||
T extends string | number | boolean | null ? T
|
||||
>T : T
|
||||
>null : null
|
||||
>T : T
|
||||
|
||||
: T extends undefined | Function ? never // undefined and functions are removed
|
||||
>T : T
|
||||
>Function : Function
|
||||
|
||||
: T extends { toJSON(): infer R } ? R // toJSON is called if it exists (e.g. Date)
|
||||
>T : T
|
||||
>toJSON : () => R
|
||||
>R : R
|
||||
>R : R
|
||||
|
||||
: T extends object ? JsonifiedObject<T>
|
||||
>T : T
|
||||
>JsonifiedObject : JsonifiedObject<T>
|
||||
>T : T
|
||||
|
||||
: "what is this";
|
||||
|
||||
type Example = {
|
||||
>Example : Example
|
||||
|
||||
str: "literalstring",
|
||||
>str : "literalstring"
|
||||
|
||||
fn: () => void,
|
||||
>fn : () => void
|
||||
|
||||
date: Date,
|
||||
>date : Date
|
||||
>Date : Date
|
||||
|
||||
customClass: MyClass,
|
||||
>customClass : MyClass
|
||||
>MyClass : MyClass
|
||||
|
||||
obj: {
|
||||
>obj : { prop: "property"; clz: MyClass; nested: { attr: Date; }; }
|
||||
|
||||
prop: "property",
|
||||
>prop : "property"
|
||||
|
||||
clz: MyClass,
|
||||
>clz : MyClass
|
||||
>MyClass : MyClass
|
||||
|
||||
nested: { attr: Date }
|
||||
>nested : { attr: Date; }
|
||||
>attr : Date
|
||||
>Date : Date
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
declare class MyClass {
|
||||
>MyClass : MyClass
|
||||
|
||||
toJSON(): "correct";
|
||||
>toJSON : () => "correct"
|
||||
}
|
||||
|
||||
type JsonifiedExample = Jsonified<Example>;
|
||||
>JsonifiedExample : JsonifiedObject<Example>
|
||||
>Jsonified : Jsonified<T>
|
||||
>Example : Example
|
||||
|
||||
declare let ex: JsonifiedExample;
|
||||
>ex : JsonifiedObject<Example>
|
||||
>JsonifiedExample : JsonifiedObject<Example>
|
||||
|
||||
const z1: "correct" = ex.customClass;
|
||||
>z1 : "correct"
|
||||
>ex.customClass : "correct"
|
||||
>ex : JsonifiedObject<Example>
|
||||
>customClass : "correct"
|
||||
|
||||
const z2: string = ex.obj.nested.attr;
|
||||
>z2 : string
|
||||
>ex.obj.nested.attr : string
|
||||
>ex.obj.nested : JsonifiedObject<{ attr: Date; }>
|
||||
>ex.obj : JsonifiedObject<{ prop: "property"; clz: MyClass; nested: { attr: Date; }; }>
|
||||
>ex : JsonifiedObject<Example>
|
||||
>obj : JsonifiedObject<{ prop: "property"; clz: MyClass; nested: { attr: Date; }; }>
|
||||
>nested : JsonifiedObject<{ attr: Date; }>
|
||||
>attr : string
|
||||
|
||||
|
||||
@@ -73,3 +73,35 @@ type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number
|
||||
type T60 = infer U; // Error
|
||||
type T61<T> = infer A extends infer B ? infer C : infer D; // Error
|
||||
type T62<T> = U extends (infer U)[] ? U : U; // Error
|
||||
|
||||
// Example from #21496
|
||||
|
||||
type JsonifiedObject<T extends object> = { [K in keyof T]: Jsonified<T[K]> };
|
||||
|
||||
type Jsonified<T> =
|
||||
T extends string | number | boolean | null ? T
|
||||
: T extends undefined | Function ? never // undefined and functions are removed
|
||||
: T extends { toJSON(): infer R } ? R // toJSON is called if it exists (e.g. Date)
|
||||
: T extends object ? JsonifiedObject<T>
|
||||
: "what is this";
|
||||
|
||||
type Example = {
|
||||
str: "literalstring",
|
||||
fn: () => void,
|
||||
date: Date,
|
||||
customClass: MyClass,
|
||||
obj: {
|
||||
prop: "property",
|
||||
clz: MyClass,
|
||||
nested: { attr: Date }
|
||||
},
|
||||
}
|
||||
|
||||
declare class MyClass {
|
||||
toJSON(): "correct";
|
||||
}
|
||||
|
||||
type JsonifiedExample = Jsonified<Example>;
|
||||
declare let ex: JsonifiedExample;
|
||||
const z1: "correct" = ex.customClass;
|
||||
const z2: string = ex.obj.nested.attr;
|
||||
|
||||
Reference in New Issue
Block a user