Merge pull request #19564 from Microsoft/fixGenericMappedTypeRelationships
Fix generic mapped type relationships
This commit is contained in:
commit
7f4a132af9
|
@ -9460,32 +9460,30 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (isGenericMappedType(target) && !isGenericMappedType(source) && getConstraintTypeFromMappedType(<MappedType>target) === getIndexType(source)) {
|
||||
// A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X.
|
||||
const indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(<MappedType>target));
|
||||
const templateType = getTemplateTypeFromMappedType(<MappedType>target);
|
||||
if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (source.flags & TypeFlags.TypeParameter) {
|
||||
// A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X.
|
||||
if (getObjectFlags(target) & ObjectFlags.Mapped && getConstraintTypeFromMappedType(<MappedType>target) === getIndexType(source)) {
|
||||
const indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(<MappedType>target));
|
||||
const templateType = getTemplateTypeFromMappedType(<MappedType>target);
|
||||
if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
|
||||
let constraint = getConstraintOfTypeParameter(<TypeParameter>source);
|
||||
// A type parameter with no constraint is not related to the non-primitive object type.
|
||||
if (constraint || !(target.flags & TypeFlags.NonPrimitive)) {
|
||||
if (!constraint || constraint.flags & TypeFlags.Any) {
|
||||
constraint = emptyObjectType;
|
||||
}
|
||||
// Report constraint errors only if the constraint is not the empty object type
|
||||
const reportConstraintErrors = reportErrors && constraint !== emptyObjectType;
|
||||
if (result = isRelatedTo(constraint, target, reportConstraintErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else {
|
||||
let constraint = getConstraintOfTypeParameter(<TypeParameter>source);
|
||||
// A type parameter with no constraint is not related to the non-primitive object type.
|
||||
if (constraint || !(target.flags & TypeFlags.NonPrimitive)) {
|
||||
if (!constraint || constraint.flags & TypeFlags.Any) {
|
||||
constraint = emptyObjectType;
|
||||
}
|
||||
// Report constraint errors only if the constraint is not the empty object type
|
||||
const reportConstraintErrors = reportErrors && constraint !== emptyObjectType;
|
||||
if (result = isRelatedTo(constraint, target, reportConstraintErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (source.flags & TypeFlags.IndexedAccess) {
|
||||
// A type S[K] is related to a type T if A[K] is related to T, where K is string-like and
|
||||
|
|
|
@ -460,4 +460,16 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
|
|||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
}
|
||||
|
||||
function f80<T>(t: T): Partial<T> {
|
||||
return t;
|
||||
}
|
||||
|
||||
function f81<T, K extends keyof T>(t: T, k: K): Partial<T[K]> {
|
||||
return t[k];
|
||||
}
|
||||
|
||||
function f82<T, K1 extends keyof T, K2 extends keyof T[K1]>(t: T, k1: K1, k2: K2): Partial<T[K1][K2]> {
|
||||
return t[k1][k2];
|
||||
}
|
||||
|
|
@ -168,6 +168,18 @@ function f76<T, U extends T, K extends keyof T>(x: { [P in K]: T[P] }, y: { [P i
|
|||
x = y;
|
||||
y = x; // Error
|
||||
}
|
||||
|
||||
function f80<T>(t: T): Partial<T> {
|
||||
return t;
|
||||
}
|
||||
|
||||
function f81<T, K extends keyof T>(t: T, k: K): Partial<T[K]> {
|
||||
return t[k];
|
||||
}
|
||||
|
||||
function f82<T, K1 extends keyof T, K2 extends keyof T[K1]>(t: T, k1: K1, k2: K2): Partial<T[K1][K2]> {
|
||||
return t[k1][k2];
|
||||
}
|
||||
|
||||
|
||||
//// [mappedTypeRelationships.js]
|
||||
|
@ -289,6 +301,15 @@ function f76(x, y) {
|
|||
x = y;
|
||||
y = x; // Error
|
||||
}
|
||||
function f80(t) {
|
||||
return t;
|
||||
}
|
||||
function f81(t, k) {
|
||||
return t[k];
|
||||
}
|
||||
function f82(t, k1, k2) {
|
||||
return t[k1][k2];
|
||||
}
|
||||
|
||||
|
||||
//// [mappedTypeRelationships.d.ts]
|
||||
|
@ -369,3 +390,6 @@ declare function f76<T, U extends T, K extends keyof T>(x: {
|
|||
}, y: {
|
||||
[P in K]: U[P];
|
||||
}): void;
|
||||
declare function f80<T>(t: T): Partial<T>;
|
||||
declare function f81<T, K extends keyof T>(t: T, k: K): Partial<T[K]>;
|
||||
declare function f82<T, K1 extends keyof T, K2 extends keyof T[K1]>(t: T, k1: K1, k2: K2): Partial<T[K1][K2]>;
|
||||
|
|
|
@ -750,3 +750,58 @@ function f76<T, U extends T, K extends keyof T>(x: { [P in K]: T[P] }, y: { [P i
|
|||
>x : Symbol(x, Decl(mappedTypeRelationships.ts, 165, 48))
|
||||
}
|
||||
|
||||
function f80<T>(t: T): Partial<T> {
|
||||
>f80 : Symbol(f80, Decl(mappedTypeRelationships.ts, 168, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeRelationships.ts, 170, 13))
|
||||
>t : Symbol(t, Decl(mappedTypeRelationships.ts, 170, 16))
|
||||
>T : Symbol(T, Decl(mappedTypeRelationships.ts, 170, 13))
|
||||
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(mappedTypeRelationships.ts, 170, 13))
|
||||
|
||||
return t;
|
||||
>t : Symbol(t, Decl(mappedTypeRelationships.ts, 170, 16))
|
||||
}
|
||||
|
||||
function f81<T, K extends keyof T>(t: T, k: K): Partial<T[K]> {
|
||||
>f81 : Symbol(f81, Decl(mappedTypeRelationships.ts, 172, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeRelationships.ts, 174, 13))
|
||||
>K : Symbol(K, Decl(mappedTypeRelationships.ts, 174, 15))
|
||||
>T : Symbol(T, Decl(mappedTypeRelationships.ts, 174, 13))
|
||||
>t : Symbol(t, Decl(mappedTypeRelationships.ts, 174, 35))
|
||||
>T : Symbol(T, Decl(mappedTypeRelationships.ts, 174, 13))
|
||||
>k : Symbol(k, Decl(mappedTypeRelationships.ts, 174, 40))
|
||||
>K : Symbol(K, Decl(mappedTypeRelationships.ts, 174, 15))
|
||||
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(mappedTypeRelationships.ts, 174, 13))
|
||||
>K : Symbol(K, Decl(mappedTypeRelationships.ts, 174, 15))
|
||||
|
||||
return t[k];
|
||||
>t : Symbol(t, Decl(mappedTypeRelationships.ts, 174, 35))
|
||||
>k : Symbol(k, Decl(mappedTypeRelationships.ts, 174, 40))
|
||||
}
|
||||
|
||||
function f82<T, K1 extends keyof T, K2 extends keyof T[K1]>(t: T, k1: K1, k2: K2): Partial<T[K1][K2]> {
|
||||
>f82 : Symbol(f82, Decl(mappedTypeRelationships.ts, 176, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeRelationships.ts, 178, 13))
|
||||
>K1 : Symbol(K1, Decl(mappedTypeRelationships.ts, 178, 15))
|
||||
>T : Symbol(T, Decl(mappedTypeRelationships.ts, 178, 13))
|
||||
>K2 : Symbol(K2, Decl(mappedTypeRelationships.ts, 178, 35))
|
||||
>T : Symbol(T, Decl(mappedTypeRelationships.ts, 178, 13))
|
||||
>K1 : Symbol(K1, Decl(mappedTypeRelationships.ts, 178, 15))
|
||||
>t : Symbol(t, Decl(mappedTypeRelationships.ts, 178, 60))
|
||||
>T : Symbol(T, Decl(mappedTypeRelationships.ts, 178, 13))
|
||||
>k1 : Symbol(k1, Decl(mappedTypeRelationships.ts, 178, 65))
|
||||
>K1 : Symbol(K1, Decl(mappedTypeRelationships.ts, 178, 15))
|
||||
>k2 : Symbol(k2, Decl(mappedTypeRelationships.ts, 178, 73))
|
||||
>K2 : Symbol(K2, Decl(mappedTypeRelationships.ts, 178, 35))
|
||||
>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(mappedTypeRelationships.ts, 178, 13))
|
||||
>K1 : Symbol(K1, Decl(mappedTypeRelationships.ts, 178, 15))
|
||||
>K2 : Symbol(K2, Decl(mappedTypeRelationships.ts, 178, 35))
|
||||
|
||||
return t[k1][k2];
|
||||
>t : Symbol(t, Decl(mappedTypeRelationships.ts, 178, 60))
|
||||
>k1 : Symbol(k1, Decl(mappedTypeRelationships.ts, 178, 65))
|
||||
>k2 : Symbol(k2, Decl(mappedTypeRelationships.ts, 178, 73))
|
||||
}
|
||||
|
||||
|
|
|
@ -856,3 +856,61 @@ function f76<T, U extends T, K extends keyof T>(x: { [P in K]: T[P] }, y: { [P i
|
|||
>x : { [P in K]: T[P]; }
|
||||
}
|
||||
|
||||
function f80<T>(t: T): Partial<T> {
|
||||
>f80 : <T>(t: T) => Partial<T>
|
||||
>T : T
|
||||
>t : T
|
||||
>T : T
|
||||
>Partial : Partial<T>
|
||||
>T : T
|
||||
|
||||
return t;
|
||||
>t : T
|
||||
}
|
||||
|
||||
function f81<T, K extends keyof T>(t: T, k: K): Partial<T[K]> {
|
||||
>f81 : <T, K extends keyof T>(t: T, k: K) => Partial<T[K]>
|
||||
>T : T
|
||||
>K : K
|
||||
>T : T
|
||||
>t : T
|
||||
>T : T
|
||||
>k : K
|
||||
>K : K
|
||||
>Partial : Partial<T>
|
||||
>T : T
|
||||
>K : K
|
||||
|
||||
return t[k];
|
||||
>t[k] : T[K]
|
||||
>t : T
|
||||
>k : K
|
||||
}
|
||||
|
||||
function f82<T, K1 extends keyof T, K2 extends keyof T[K1]>(t: T, k1: K1, k2: K2): Partial<T[K1][K2]> {
|
||||
>f82 : <T, K1 extends keyof T, K2 extends keyof T[K1]>(t: T, k1: K1, k2: K2) => Partial<T[K1][K2]>
|
||||
>T : T
|
||||
>K1 : K1
|
||||
>T : T
|
||||
>K2 : K2
|
||||
>T : T
|
||||
>K1 : K1
|
||||
>t : T
|
||||
>T : T
|
||||
>k1 : K1
|
||||
>K1 : K1
|
||||
>k2 : K2
|
||||
>K2 : K2
|
||||
>Partial : Partial<T>
|
||||
>T : T
|
||||
>K1 : K1
|
||||
>K2 : K2
|
||||
|
||||
return t[k1][k2];
|
||||
>t[k1][k2] : T[K1][K2]
|
||||
>t[k1] : T[K1]
|
||||
>t : T
|
||||
>k1 : K1
|
||||
>k2 : K2
|
||||
}
|
||||
|
||||
|
|
|
@ -170,3 +170,15 @@ function f76<T, U extends T, K extends keyof T>(x: { [P in K]: T[P] }, y: { [P i
|
|||
x = y;
|
||||
y = x; // Error
|
||||
}
|
||||
|
||||
function f80<T>(t: T): Partial<T> {
|
||||
return t;
|
||||
}
|
||||
|
||||
function f81<T, K extends keyof T>(t: T, k: K): Partial<T[K]> {
|
||||
return t[k];
|
||||
}
|
||||
|
||||
function f82<T, K1 extends keyof T, K2 extends keyof T[K1]>(t: T, k1: K1, k2: K2): Partial<T[K1][K2]> {
|
||||
return t[k1][k2];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue