mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-11 06:02:53 -05:00
Merge pull request #28170 from Microsoft/fixGenericMappedTypeConstraint
No constraint for { [P in K]: XXX } where K is type variable
This commit is contained in:
@@ -6831,11 +6831,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
// First, if the constraint type is a type parameter, obtain the base constraint. Then,
|
||||
// if the key type is a 'keyof X', obtain 'keyof C' where C is the base constraint of X.
|
||||
// Finally, iterate over the constituents of the resulting iteration type.
|
||||
const keyType = constraintType.flags & TypeFlags.InstantiableNonPrimitive ? getApparentType(constraintType) : constraintType;
|
||||
const iterationType = keyType.flags & TypeFlags.Index ? getIndexType(getApparentType((<IndexType>keyType).type)) : keyType;
|
||||
// If the key type is a 'keyof X', obtain 'keyof C' where C is the base constraint of X.
|
||||
// Then iterate over the constituents of the key type.
|
||||
const iterationType = constraintType.flags & TypeFlags.Index ? getIndexType(getApparentType((<IndexType>constraintType).type)) : constraintType;
|
||||
forEachType(iterationType, addMemberForKeyType);
|
||||
}
|
||||
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
|
||||
@@ -39,9 +39,11 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(130,39): error TS2322:
|
||||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(136,16): error TS2322: Type 'T' is not assignable to type 'string | number | symbol'.
|
||||
Type 'T' is not assignable to type 'symbol'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(136,21): error TS2536: Type 'P' cannot be used to index type 'T'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(148,17): error TS2339: Property 'foo' does not exist on type 'Pick<T, K>'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeErrors.ts(152,17): error TS2339: Property 'foo' does not exist on type 'Record<K, number>'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (25 errors) ====
|
||||
==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (27 errors) ====
|
||||
interface Shape {
|
||||
name: string;
|
||||
width: number;
|
||||
@@ -256,4 +258,18 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(136,21): error TS2536:
|
||||
pf: {x: 7},
|
||||
pt: {x: 7, y: false},
|
||||
};
|
||||
|
||||
// Repro from #28170
|
||||
|
||||
function test1<T, K extends keyof T>(obj: Pick<T, K>) {
|
||||
let x = obj.foo; // Error
|
||||
~~~
|
||||
!!! error TS2339: Property 'foo' does not exist on type 'Pick<T, K>'.
|
||||
}
|
||||
|
||||
function test2<T, K extends keyof T>(obj: Record<K, number>) {
|
||||
let x = obj.foo; // Error
|
||||
~~~
|
||||
!!! error TS2339: Property 'foo' does not exist on type 'Record<K, number>'.
|
||||
}
|
||||
|
||||
@@ -142,6 +142,16 @@ let f: Foo2<O, 'x'> = {
|
||||
pf: {x: 7},
|
||||
pt: {x: 7, y: false},
|
||||
};
|
||||
|
||||
// Repro from #28170
|
||||
|
||||
function test1<T, K extends keyof T>(obj: Pick<T, K>) {
|
||||
let x = obj.foo; // Error
|
||||
}
|
||||
|
||||
function test2<T, K extends keyof T>(obj: Record<K, number>) {
|
||||
let x = obj.foo; // Error
|
||||
}
|
||||
|
||||
|
||||
//// [mappedTypeErrors.js]
|
||||
@@ -222,6 +232,13 @@ var f = {
|
||||
pf: { x: 7 },
|
||||
pt: { x: 7, y: false }
|
||||
};
|
||||
// Repro from #28170
|
||||
function test1(obj) {
|
||||
var x = obj.foo; // Error
|
||||
}
|
||||
function test2(obj) {
|
||||
var x = obj.foo; // Error
|
||||
}
|
||||
|
||||
|
||||
//// [mappedTypeErrors.d.ts]
|
||||
@@ -300,3 +317,5 @@ declare type O = {
|
||||
};
|
||||
declare let o: O;
|
||||
declare let f: Foo2<O, 'x'>;
|
||||
declare function test1<T, K extends keyof T>(obj: Pick<T, K>): void;
|
||||
declare function test2<T, K extends keyof T>(obj: Record<K, number>): void;
|
||||
|
||||
@@ -540,3 +540,34 @@ let f: Foo2<O, 'x'> = {
|
||||
|
||||
};
|
||||
|
||||
// Repro from #28170
|
||||
|
||||
function test1<T, K extends keyof T>(obj: Pick<T, K>) {
|
||||
>test1 : Symbol(test1, Decl(mappedTypeErrors.ts, 142, 2))
|
||||
>T : Symbol(T, Decl(mappedTypeErrors.ts, 146, 15))
|
||||
>K : Symbol(K, Decl(mappedTypeErrors.ts, 146, 17))
|
||||
>T : Symbol(T, Decl(mappedTypeErrors.ts, 146, 15))
|
||||
>obj : Symbol(obj, Decl(mappedTypeErrors.ts, 146, 37))
|
||||
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(mappedTypeErrors.ts, 146, 15))
|
||||
>K : Symbol(K, Decl(mappedTypeErrors.ts, 146, 17))
|
||||
|
||||
let x = obj.foo; // Error
|
||||
>x : Symbol(x, Decl(mappedTypeErrors.ts, 147, 7))
|
||||
>obj : Symbol(obj, Decl(mappedTypeErrors.ts, 146, 37))
|
||||
}
|
||||
|
||||
function test2<T, K extends keyof T>(obj: Record<K, number>) {
|
||||
>test2 : Symbol(test2, Decl(mappedTypeErrors.ts, 148, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeErrors.ts, 150, 15))
|
||||
>K : Symbol(K, Decl(mappedTypeErrors.ts, 150, 17))
|
||||
>T : Symbol(T, Decl(mappedTypeErrors.ts, 150, 15))
|
||||
>obj : Symbol(obj, Decl(mappedTypeErrors.ts, 150, 37))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
>K : Symbol(K, Decl(mappedTypeErrors.ts, 150, 17))
|
||||
|
||||
let x = obj.foo; // Error
|
||||
>x : Symbol(x, Decl(mappedTypeErrors.ts, 151, 7))
|
||||
>obj : Symbol(obj, Decl(mappedTypeErrors.ts, 150, 37))
|
||||
}
|
||||
|
||||
|
||||
@@ -501,3 +501,27 @@ let f: Foo2<O, 'x'> = {
|
||||
|
||||
};
|
||||
|
||||
// Repro from #28170
|
||||
|
||||
function test1<T, K extends keyof T>(obj: Pick<T, K>) {
|
||||
>test1 : <T, K extends keyof T>(obj: Pick<T, K>) => void
|
||||
>obj : Pick<T, K>
|
||||
|
||||
let x = obj.foo; // Error
|
||||
>x : any
|
||||
>obj.foo : any
|
||||
>obj : Pick<T, K>
|
||||
>foo : any
|
||||
}
|
||||
|
||||
function test2<T, K extends keyof T>(obj: Record<K, number>) {
|
||||
>test2 : <T, K extends keyof T>(obj: Record<K, number>) => void
|
||||
>obj : Record<K, number>
|
||||
|
||||
let x = obj.foo; // Error
|
||||
>x : any
|
||||
>obj.foo : any
|
||||
>obj : Record<K, number>
|
||||
>foo : any
|
||||
}
|
||||
|
||||
|
||||
@@ -144,3 +144,13 @@ let f: Foo2<O, 'x'> = {
|
||||
pf: {x: 7},
|
||||
pt: {x: 7, y: false},
|
||||
};
|
||||
|
||||
// Repro from #28170
|
||||
|
||||
function test1<T, K extends keyof T>(obj: Pick<T, K>) {
|
||||
let x = obj.foo; // Error
|
||||
}
|
||||
|
||||
function test2<T, K extends keyof T>(obj: Record<K, number>) {
|
||||
let x = obj.foo; // Error
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user