mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Merge pull request #29787 from Microsoft/inferToPartiallyHomomorphic
Infer to partially homomorphic types (such as Pick<T, K>)
This commit is contained in:
commit
d66000bc47
@ -14580,11 +14580,11 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function inferFromMappedTypeConstraint(source: Type, target: Type, constraintType: Type): boolean {
|
||||
function inferToMappedType(source: Type, target: MappedType, constraintType: Type): boolean {
|
||||
if (constraintType.flags & TypeFlags.Union) {
|
||||
let result = false;
|
||||
for (const type of (constraintType as UnionType).types) {
|
||||
result = inferFromMappedTypeConstraint(source, target, type) || result;
|
||||
result = inferToMappedType(source, target, type) || result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -14595,7 +14595,7 @@ namespace ts {
|
||||
// such that direct inferences to T get priority over inferences to Partial<T>, for example.
|
||||
const inference = getInferenceInfoForType((<IndexType>constraintType).type);
|
||||
if (inference && !inference.isFixed) {
|
||||
const inferredType = inferTypeForHomomorphicMappedType(source, <MappedType>target, constraintType as IndexType);
|
||||
const inferredType = inferTypeForHomomorphicMappedType(source, target, <IndexType>constraintType);
|
||||
if (inferredType) {
|
||||
const savePriority = priority;
|
||||
priority |= InferencePriority.HomomorphicMappedType;
|
||||
@ -14606,18 +14606,28 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
if (constraintType.flags & TypeFlags.TypeParameter) {
|
||||
// We're inferring from some source type S to a mapped type { [P in T]: X }, where T is a type
|
||||
// parameter. Infer from 'keyof S' to T and infer from a union of each property type in S to X.
|
||||
// We're inferring from some source type S to a mapped type { [P in K]: X }, where K is a type
|
||||
// parameter. First infer from 'keyof S' to K.
|
||||
const savePriority = priority;
|
||||
priority |= InferencePriority.MappedTypeConstraint;
|
||||
inferFromTypes(getIndexType(source), constraintType);
|
||||
priority = savePriority;
|
||||
// If K is constrained to a type C, also infer to C. Thus, for a mapped type { [P in K]: X },
|
||||
// where K extends keyof T, we make the same inferences as for a homomorphic mapped type
|
||||
// { [P in keyof T]: X }. This enables us to make meaningful inferences when the target is a
|
||||
// Pick<T, K>.
|
||||
const extendedConstraint = getConstraintOfType(constraintType);
|
||||
if (extendedConstraint && inferToMappedType(source, target, extendedConstraint)) {
|
||||
return true;
|
||||
}
|
||||
// If no inferences can be made to K's constraint, infer from a union of the property types
|
||||
// in the source to the template type X.
|
||||
const valueTypes = compact([
|
||||
getIndexTypeOfType(source, IndexKind.String),
|
||||
getIndexTypeOfType(source, IndexKind.Number),
|
||||
...map(getPropertiesOfType(source), getTypeOfSymbol)
|
||||
]);
|
||||
inferFromTypes(getUnionType(valueTypes), getTemplateTypeFromMappedType(<MappedType>target));
|
||||
inferFromTypes(getUnionType(valueTypes), getTemplateTypeFromMappedType(target));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -14632,7 +14642,7 @@ namespace ts {
|
||||
}
|
||||
if (getObjectFlags(target) & ObjectFlags.Mapped) {
|
||||
const constraintType = getConstraintTypeFromMappedType(<MappedType>target);
|
||||
if (inferFromMappedTypeConstraint(source, target, constraintType)) {
|
||||
if (inferToMappedType(source, <MappedType>target, constraintType)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,7 +149,35 @@ var g2 = applySpec({ foo: { bar: { baz: (x: any) => true } } });
|
||||
const foo = <T>(object: T, partial: Partial<T>) => object;
|
||||
let o = {a: 5, b: 7};
|
||||
foo(o, {b: 9});
|
||||
o = foo(o, {b: 9});
|
||||
o = foo(o, {b: 9});
|
||||
|
||||
// Inferring to { [P in K]: X }, where K extends keyof T, produces same inferences as
|
||||
// inferring to { [P in keyof T]: X }.
|
||||
|
||||
declare function f20<T, K extends keyof T>(obj: Pick<T, K>): T;
|
||||
declare function f21<T, K extends keyof T>(obj: Pick<T, K>): K;
|
||||
declare function f22<T, K extends keyof T>(obj: Boxified<Pick<T, K>>): T;
|
||||
declare function f23<T, U extends keyof T, K extends U>(obj: Pick<T, K>): T;
|
||||
declare function f24<T, U, K extends keyof T | keyof U>(obj: Pick<T & U, K>): T & U;
|
||||
|
||||
let x0 = f20({ foo: 42, bar: "hello" });
|
||||
let x1 = f21({ foo: 42, bar: "hello" });
|
||||
let x2 = f22({ foo: { value: 42} , bar: { value: "hello" } });
|
||||
let x3 = f23({ foo: 42, bar: "hello" });
|
||||
let x4 = f24({ foo: 42, bar: "hello" });
|
||||
|
||||
// Repro from #29765
|
||||
|
||||
function getProps<T, K extends keyof T>(obj: T, list: K[]): Pick<T, K> {
|
||||
return {} as any;
|
||||
}
|
||||
|
||||
const myAny: any = {};
|
||||
|
||||
const o1 = getProps(myAny, ['foo', 'bar']);
|
||||
|
||||
const o2: { foo: any; bar: any } = getProps(myAny, ['foo', 'bar']);
|
||||
|
||||
|
||||
//// [isomorphicMappedTypeInference.js]
|
||||
function box(x) {
|
||||
@ -255,6 +283,18 @@ var foo = function (object, partial) { return object; };
|
||||
var o = { a: 5, b: 7 };
|
||||
foo(o, { b: 9 });
|
||||
o = foo(o, { b: 9 });
|
||||
var x0 = f20({ foo: 42, bar: "hello" });
|
||||
var x1 = f21({ foo: 42, bar: "hello" });
|
||||
var x2 = f22({ foo: { value: 42 }, bar: { value: "hello" } });
|
||||
var x3 = f23({ foo: 42, bar: "hello" });
|
||||
var x4 = f24({ foo: 42, bar: "hello" });
|
||||
// Repro from #29765
|
||||
function getProps(obj, list) {
|
||||
return {};
|
||||
}
|
||||
var myAny = {};
|
||||
var o1 = getProps(myAny, ['foo', 'bar']);
|
||||
var o2 = getProps(myAny, ['foo', 'bar']);
|
||||
|
||||
|
||||
//// [isomorphicMappedTypeInference.d.ts]
|
||||
@ -323,3 +363,35 @@ declare let o: {
|
||||
a: number;
|
||||
b: number;
|
||||
};
|
||||
declare function f20<T, K extends keyof T>(obj: Pick<T, K>): T;
|
||||
declare function f21<T, K extends keyof T>(obj: Pick<T, K>): K;
|
||||
declare function f22<T, K extends keyof T>(obj: Boxified<Pick<T, K>>): T;
|
||||
declare function f23<T, U extends keyof T, K extends U>(obj: Pick<T, K>): T;
|
||||
declare function f24<T, U, K extends keyof T | keyof U>(obj: Pick<T & U, K>): T & U;
|
||||
declare let x0: {
|
||||
foo: number;
|
||||
bar: string;
|
||||
};
|
||||
declare let x1: "foo" | "bar";
|
||||
declare let x2: {
|
||||
foo: number;
|
||||
bar: string;
|
||||
};
|
||||
declare let x3: {
|
||||
foo: number;
|
||||
bar: string;
|
||||
};
|
||||
declare let x4: {
|
||||
foo: number;
|
||||
bar: string;
|
||||
} & {
|
||||
foo: number;
|
||||
bar: string;
|
||||
};
|
||||
declare function getProps<T, K extends keyof T>(obj: T, list: K[]): Pick<T, K>;
|
||||
declare const myAny: any;
|
||||
declare const o1: Pick<any, "foo" | "bar">;
|
||||
declare const o2: {
|
||||
foo: any;
|
||||
bar: any;
|
||||
};
|
||||
|
||||
@ -486,3 +486,133 @@ o = foo(o, {b: 9});
|
||||
>o : Symbol(o, Decl(isomorphicMappedTypeInference.ts, 148, 3))
|
||||
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 150, 12))
|
||||
|
||||
// Inferring to { [P in K]: X }, where K extends keyof T, produces same inferences as
|
||||
// inferring to { [P in keyof T]: X }.
|
||||
|
||||
declare function f20<T, K extends keyof T>(obj: Pick<T, K>): T;
|
||||
>f20 : Symbol(f20, Decl(isomorphicMappedTypeInference.ts, 150, 19))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 155, 21))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 155, 23))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 155, 21))
|
||||
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 155, 43))
|
||||
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 155, 21))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 155, 23))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 155, 21))
|
||||
|
||||
declare function f21<T, K extends keyof T>(obj: Pick<T, K>): K;
|
||||
>f21 : Symbol(f21, Decl(isomorphicMappedTypeInference.ts, 155, 63))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 156, 21))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 156, 23))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 156, 21))
|
||||
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 156, 43))
|
||||
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 156, 21))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 156, 23))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 156, 23))
|
||||
|
||||
declare function f22<T, K extends keyof T>(obj: Boxified<Pick<T, K>>): T;
|
||||
>f22 : Symbol(f22, Decl(isomorphicMappedTypeInference.ts, 156, 63))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 157, 21))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 157, 23))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 157, 21))
|
||||
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 157, 43))
|
||||
>Boxified : Symbol(Boxified, Decl(isomorphicMappedTypeInference.ts, 2, 1))
|
||||
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 157, 21))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 157, 23))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 157, 21))
|
||||
|
||||
declare function f23<T, U extends keyof T, K extends U>(obj: Pick<T, K>): T;
|
||||
>f23 : Symbol(f23, Decl(isomorphicMappedTypeInference.ts, 157, 73))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 158, 21))
|
||||
>U : Symbol(U, Decl(isomorphicMappedTypeInference.ts, 158, 23))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 158, 21))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 158, 42))
|
||||
>U : Symbol(U, Decl(isomorphicMappedTypeInference.ts, 158, 23))
|
||||
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 158, 56))
|
||||
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 158, 21))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 158, 42))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 158, 21))
|
||||
|
||||
declare function f24<T, U, K extends keyof T | keyof U>(obj: Pick<T & U, K>): T & U;
|
||||
>f24 : Symbol(f24, Decl(isomorphicMappedTypeInference.ts, 158, 76))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 159, 21))
|
||||
>U : Symbol(U, Decl(isomorphicMappedTypeInference.ts, 159, 23))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 159, 26))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 159, 21))
|
||||
>U : Symbol(U, Decl(isomorphicMappedTypeInference.ts, 159, 23))
|
||||
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 159, 56))
|
||||
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 159, 21))
|
||||
>U : Symbol(U, Decl(isomorphicMappedTypeInference.ts, 159, 23))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 159, 26))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 159, 21))
|
||||
>U : Symbol(U, Decl(isomorphicMappedTypeInference.ts, 159, 23))
|
||||
|
||||
let x0 = f20({ foo: 42, bar: "hello" });
|
||||
>x0 : Symbol(x0, Decl(isomorphicMappedTypeInference.ts, 161, 3))
|
||||
>f20 : Symbol(f20, Decl(isomorphicMappedTypeInference.ts, 150, 19))
|
||||
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 161, 14))
|
||||
>bar : Symbol(bar, Decl(isomorphicMappedTypeInference.ts, 161, 23))
|
||||
|
||||
let x1 = f21({ foo: 42, bar: "hello" });
|
||||
>x1 : Symbol(x1, Decl(isomorphicMappedTypeInference.ts, 162, 3))
|
||||
>f21 : Symbol(f21, Decl(isomorphicMappedTypeInference.ts, 155, 63))
|
||||
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 162, 14))
|
||||
>bar : Symbol(bar, Decl(isomorphicMappedTypeInference.ts, 162, 23))
|
||||
|
||||
let x2 = f22({ foo: { value: 42} , bar: { value: "hello" } });
|
||||
>x2 : Symbol(x2, Decl(isomorphicMappedTypeInference.ts, 163, 3))
|
||||
>f22 : Symbol(f22, Decl(isomorphicMappedTypeInference.ts, 156, 63))
|
||||
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 163, 14))
|
||||
>value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 163, 21))
|
||||
>bar : Symbol(bar, Decl(isomorphicMappedTypeInference.ts, 163, 34))
|
||||
>value : Symbol(value, Decl(isomorphicMappedTypeInference.ts, 163, 41))
|
||||
|
||||
let x3 = f23({ foo: 42, bar: "hello" });
|
||||
>x3 : Symbol(x3, Decl(isomorphicMappedTypeInference.ts, 164, 3))
|
||||
>f23 : Symbol(f23, Decl(isomorphicMappedTypeInference.ts, 157, 73))
|
||||
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 164, 14))
|
||||
>bar : Symbol(bar, Decl(isomorphicMappedTypeInference.ts, 164, 23))
|
||||
|
||||
let x4 = f24({ foo: 42, bar: "hello" });
|
||||
>x4 : Symbol(x4, Decl(isomorphicMappedTypeInference.ts, 165, 3))
|
||||
>f24 : Symbol(f24, Decl(isomorphicMappedTypeInference.ts, 158, 76))
|
||||
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 165, 14))
|
||||
>bar : Symbol(bar, Decl(isomorphicMappedTypeInference.ts, 165, 23))
|
||||
|
||||
// Repro from #29765
|
||||
|
||||
function getProps<T, K extends keyof T>(obj: T, list: K[]): Pick<T, K> {
|
||||
>getProps : Symbol(getProps, Decl(isomorphicMappedTypeInference.ts, 165, 40))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 169, 18))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 169, 20))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 169, 18))
|
||||
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 169, 40))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 169, 18))
|
||||
>list : Symbol(list, Decl(isomorphicMappedTypeInference.ts, 169, 47))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 169, 20))
|
||||
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 169, 18))
|
||||
>K : Symbol(K, Decl(isomorphicMappedTypeInference.ts, 169, 20))
|
||||
|
||||
return {} as any;
|
||||
}
|
||||
|
||||
const myAny: any = {};
|
||||
>myAny : Symbol(myAny, Decl(isomorphicMappedTypeInference.ts, 173, 5))
|
||||
|
||||
const o1 = getProps(myAny, ['foo', 'bar']);
|
||||
>o1 : Symbol(o1, Decl(isomorphicMappedTypeInference.ts, 175, 5))
|
||||
>getProps : Symbol(getProps, Decl(isomorphicMappedTypeInference.ts, 165, 40))
|
||||
>myAny : Symbol(myAny, Decl(isomorphicMappedTypeInference.ts, 173, 5))
|
||||
|
||||
const o2: { foo: any; bar: any } = getProps(myAny, ['foo', 'bar']);
|
||||
>o2 : Symbol(o2, Decl(isomorphicMappedTypeInference.ts, 177, 5))
|
||||
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 177, 11))
|
||||
>bar : Symbol(bar, Decl(isomorphicMappedTypeInference.ts, 177, 21))
|
||||
>getProps : Symbol(getProps, Decl(isomorphicMappedTypeInference.ts, 165, 40))
|
||||
>myAny : Symbol(myAny, Decl(isomorphicMappedTypeInference.ts, 173, 5))
|
||||
|
||||
|
||||
@ -507,3 +507,116 @@ o = foo(o, {b: 9});
|
||||
>b : number
|
||||
>9 : 9
|
||||
|
||||
// Inferring to { [P in K]: X }, where K extends keyof T, produces same inferences as
|
||||
// inferring to { [P in keyof T]: X }.
|
||||
|
||||
declare function f20<T, K extends keyof T>(obj: Pick<T, K>): T;
|
||||
>f20 : <T, K extends keyof T>(obj: Pick<T, K>) => T
|
||||
>obj : Pick<T, K>
|
||||
|
||||
declare function f21<T, K extends keyof T>(obj: Pick<T, K>): K;
|
||||
>f21 : <T, K extends keyof T>(obj: Pick<T, K>) => K
|
||||
>obj : Pick<T, K>
|
||||
|
||||
declare function f22<T, K extends keyof T>(obj: Boxified<Pick<T, K>>): T;
|
||||
>f22 : <T, K extends keyof T>(obj: Boxified<Pick<T, K>>) => T
|
||||
>obj : Boxified<Pick<T, K>>
|
||||
|
||||
declare function f23<T, U extends keyof T, K extends U>(obj: Pick<T, K>): T;
|
||||
>f23 : <T, U extends keyof T, K extends U>(obj: Pick<T, K>) => T
|
||||
>obj : Pick<T, K>
|
||||
|
||||
declare function f24<T, U, K extends keyof T | keyof U>(obj: Pick<T & U, K>): T & U;
|
||||
>f24 : <T, U, K extends keyof T | keyof U>(obj: Pick<T & U, K>) => T & U
|
||||
>obj : Pick<T & U, K>
|
||||
|
||||
let x0 = f20({ foo: 42, bar: "hello" });
|
||||
>x0 : { foo: number; bar: string; }
|
||||
>f20({ foo: 42, bar: "hello" }) : { foo: number; bar: string; }
|
||||
>f20 : <T, K extends keyof T>(obj: Pick<T, K>) => T
|
||||
>{ foo: 42, bar: "hello" } : { foo: number; bar: string; }
|
||||
>foo : number
|
||||
>42 : 42
|
||||
>bar : string
|
||||
>"hello" : "hello"
|
||||
|
||||
let x1 = f21({ foo: 42, bar: "hello" });
|
||||
>x1 : "foo" | "bar"
|
||||
>f21({ foo: 42, bar: "hello" }) : "foo" | "bar"
|
||||
>f21 : <T, K extends keyof T>(obj: Pick<T, K>) => K
|
||||
>{ foo: 42, bar: "hello" } : { foo: number; bar: string; }
|
||||
>foo : number
|
||||
>42 : 42
|
||||
>bar : string
|
||||
>"hello" : "hello"
|
||||
|
||||
let x2 = f22({ foo: { value: 42} , bar: { value: "hello" } });
|
||||
>x2 : { foo: number; bar: string; }
|
||||
>f22({ foo: { value: 42} , bar: { value: "hello" } }) : { foo: number; bar: string; }
|
||||
>f22 : <T, K extends keyof T>(obj: Boxified<Pick<T, K>>) => T
|
||||
>{ foo: { value: 42} , bar: { value: "hello" } } : { foo: { value: number; }; bar: { value: string; }; }
|
||||
>foo : { value: number; }
|
||||
>{ value: 42} : { value: number; }
|
||||
>value : number
|
||||
>42 : 42
|
||||
>bar : { value: string; }
|
||||
>{ value: "hello" } : { value: string; }
|
||||
>value : string
|
||||
>"hello" : "hello"
|
||||
|
||||
let x3 = f23({ foo: 42, bar: "hello" });
|
||||
>x3 : { foo: number; bar: string; }
|
||||
>f23({ foo: 42, bar: "hello" }) : { foo: number; bar: string; }
|
||||
>f23 : <T, U extends keyof T, K extends U>(obj: Pick<T, K>) => T
|
||||
>{ foo: 42, bar: "hello" } : { foo: number; bar: string; }
|
||||
>foo : number
|
||||
>42 : 42
|
||||
>bar : string
|
||||
>"hello" : "hello"
|
||||
|
||||
let x4 = f24({ foo: 42, bar: "hello" });
|
||||
>x4 : { foo: number; bar: string; } & { foo: number; bar: string; }
|
||||
>f24({ foo: 42, bar: "hello" }) : { foo: number; bar: string; } & { foo: number; bar: string; }
|
||||
>f24 : <T, U, K extends keyof T | keyof U>(obj: Pick<T & U, K>) => T & U
|
||||
>{ foo: 42, bar: "hello" } : { foo: number; bar: string; }
|
||||
>foo : number
|
||||
>42 : 42
|
||||
>bar : string
|
||||
>"hello" : "hello"
|
||||
|
||||
// Repro from #29765
|
||||
|
||||
function getProps<T, K extends keyof T>(obj: T, list: K[]): Pick<T, K> {
|
||||
>getProps : <T, K extends keyof T>(obj: T, list: K[]) => Pick<T, K>
|
||||
>obj : T
|
||||
>list : K[]
|
||||
|
||||
return {} as any;
|
||||
>{} as any : any
|
||||
>{} : {}
|
||||
}
|
||||
|
||||
const myAny: any = {};
|
||||
>myAny : any
|
||||
>{} : {}
|
||||
|
||||
const o1 = getProps(myAny, ['foo', 'bar']);
|
||||
>o1 : Pick<any, "foo" | "bar">
|
||||
>getProps(myAny, ['foo', 'bar']) : Pick<any, "foo" | "bar">
|
||||
>getProps : <T, K extends keyof T>(obj: T, list: K[]) => Pick<T, K>
|
||||
>myAny : any
|
||||
>['foo', 'bar'] : ("foo" | "bar")[]
|
||||
>'foo' : "foo"
|
||||
>'bar' : "bar"
|
||||
|
||||
const o2: { foo: any; bar: any } = getProps(myAny, ['foo', 'bar']);
|
||||
>o2 : { foo: any; bar: any; }
|
||||
>foo : any
|
||||
>bar : any
|
||||
>getProps(myAny, ['foo', 'bar']) : Pick<any, "foo" | "bar">
|
||||
>getProps : <T, K extends keyof T>(obj: T, list: K[]) => Pick<T, K>
|
||||
>myAny : any
|
||||
>['foo', 'bar'] : ("foo" | "bar")[]
|
||||
>'foo' : "foo"
|
||||
>'bar' : "bar"
|
||||
|
||||
|
||||
@ -152,4 +152,31 @@ var g2 = applySpec({ foo: { bar: { baz: (x: any) => true } } });
|
||||
const foo = <T>(object: T, partial: Partial<T>) => object;
|
||||
let o = {a: 5, b: 7};
|
||||
foo(o, {b: 9});
|
||||
o = foo(o, {b: 9});
|
||||
o = foo(o, {b: 9});
|
||||
|
||||
// Inferring to { [P in K]: X }, where K extends keyof T, produces same inferences as
|
||||
// inferring to { [P in keyof T]: X }.
|
||||
|
||||
declare function f20<T, K extends keyof T>(obj: Pick<T, K>): T;
|
||||
declare function f21<T, K extends keyof T>(obj: Pick<T, K>): K;
|
||||
declare function f22<T, K extends keyof T>(obj: Boxified<Pick<T, K>>): T;
|
||||
declare function f23<T, U extends keyof T, K extends U>(obj: Pick<T, K>): T;
|
||||
declare function f24<T, U, K extends keyof T | keyof U>(obj: Pick<T & U, K>): T & U;
|
||||
|
||||
let x0 = f20({ foo: 42, bar: "hello" });
|
||||
let x1 = f21({ foo: 42, bar: "hello" });
|
||||
let x2 = f22({ foo: { value: 42} , bar: { value: "hello" } });
|
||||
let x3 = f23({ foo: 42, bar: "hello" });
|
||||
let x4 = f24({ foo: 42, bar: "hello" });
|
||||
|
||||
// Repro from #29765
|
||||
|
||||
function getProps<T, K extends keyof T>(obj: T, list: K[]): Pick<T, K> {
|
||||
return {} as any;
|
||||
}
|
||||
|
||||
const myAny: any = {};
|
||||
|
||||
const o1 = getProps(myAny, ['foo', 'bar']);
|
||||
|
||||
const o2: { foo: any; bar: any } = getProps(myAny, ['foo', 'bar']);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user