mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-23 07:07:09 -05:00
Merge pull request #31537 from microsoft/fixIndexedAccessConstraint
Fix indexed access constraint
This commit is contained in:
@@ -7657,15 +7657,20 @@ namespace ts {
|
||||
return hasNonCircularBaseConstraint(type) ? getConstraintFromIndexedAccess(type) : undefined;
|
||||
}
|
||||
|
||||
function getSimplifiedTypeOrConstraint(type: Type) {
|
||||
const simplified = getSimplifiedType(type, /*writing*/ false);
|
||||
return simplified !== type ? simplified : getConstraintOfType(type);
|
||||
}
|
||||
|
||||
function getConstraintFromIndexedAccess(type: IndexedAccessType) {
|
||||
const indexConstraint = getConstraintOfType(type.indexType);
|
||||
const indexConstraint = getSimplifiedTypeOrConstraint(type.indexType);
|
||||
if (indexConstraint && indexConstraint !== type.indexType) {
|
||||
const indexedAccess = getIndexedAccessTypeOrUndefined(type.objectType, indexConstraint);
|
||||
if (indexedAccess) {
|
||||
return indexedAccess;
|
||||
}
|
||||
}
|
||||
const objectConstraint = getConstraintOfType(type.objectType);
|
||||
const objectConstraint = getSimplifiedTypeOrConstraint(type.objectType);
|
||||
if (objectConstraint && objectConstraint !== type.objectType) {
|
||||
return getIndexedAccessTypeOrUndefined(objectConstraint, type.indexType);
|
||||
}
|
||||
@@ -13061,8 +13066,7 @@ namespace ts {
|
||||
}
|
||||
// A type S is assignable to keyof T if S is assignable to keyof C, where C is the
|
||||
// simplified form of T or, if T doesn't simplify, the constraint of T.
|
||||
const simplified = getSimplifiedType((<IndexType>target).type, /*writing*/ false);
|
||||
const constraint = simplified !== (<IndexType>target).type ? simplified : getConstraintOfType((<IndexType>target).type);
|
||||
const constraint = getSimplifiedTypeOrConstraint((<IndexType>target).type);
|
||||
if (constraint) {
|
||||
// We require Ternary.True here such that circular constraints don't cause
|
||||
// false positives. For example, given 'T extends { [K in keyof T]: string }',
|
||||
|
||||
@@ -228,4 +228,14 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS23
|
||||
this["a"] = "b";
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #31385
|
||||
|
||||
type Foo<T> = { [key: string]: { [K in keyof T]: K }[keyof T] };
|
||||
|
||||
type Bar<T> = { [key: string]: { [K in keyof T]: [K] }[keyof T] };
|
||||
|
||||
type Baz<T, Q extends Foo<T>> = { [K in keyof Q]: T[Q[K]] };
|
||||
|
||||
type Qux<T, Q extends Bar<T>> = { [K in keyof Q]: T[Q[K]["0"]] };
|
||||
|
||||
@@ -145,6 +145,16 @@ export class c {
|
||||
this["a"] = "b";
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #31385
|
||||
|
||||
type Foo<T> = { [key: string]: { [K in keyof T]: K }[keyof T] };
|
||||
|
||||
type Bar<T> = { [key: string]: { [K in keyof T]: [K] }[keyof T] };
|
||||
|
||||
type Baz<T, Q extends Foo<T>> = { [K in keyof Q]: T[Q[K]] };
|
||||
|
||||
type Qux<T, Q extends Bar<T>> = { [K in keyof Q]: T[Q[K]["0"]] };
|
||||
|
||||
|
||||
//// [keyofAndIndexedAccess2.js]
|
||||
|
||||
@@ -517,3 +517,47 @@ export class c {
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #31385
|
||||
|
||||
type Foo<T> = { [key: string]: { [K in keyof T]: K }[keyof T] };
|
||||
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess2.ts, 145, 1))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 149, 9))
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccess2.ts, 149, 17))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 149, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 149, 9))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 149, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 149, 9))
|
||||
|
||||
type Bar<T> = { [key: string]: { [K in keyof T]: [K] }[keyof T] };
|
||||
>Bar : Symbol(Bar, Decl(keyofAndIndexedAccess2.ts, 149, 64))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 151, 9))
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccess2.ts, 151, 17))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 151, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 151, 9))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 151, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 151, 9))
|
||||
|
||||
type Baz<T, Q extends Foo<T>> = { [K in keyof Q]: T[Q[K]] };
|
||||
>Baz : Symbol(Baz, Decl(keyofAndIndexedAccess2.ts, 151, 66))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 153, 9))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 153, 11))
|
||||
>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess2.ts, 145, 1))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 153, 9))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 153, 35))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 153, 11))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 153, 9))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 153, 11))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 153, 35))
|
||||
|
||||
type Qux<T, Q extends Bar<T>> = { [K in keyof Q]: T[Q[K]["0"]] };
|
||||
>Qux : Symbol(Qux, Decl(keyofAndIndexedAccess2.ts, 153, 60))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 155, 9))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 155, 11))
|
||||
>Bar : Symbol(Bar, Decl(keyofAndIndexedAccess2.ts, 149, 64))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 155, 9))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 155, 35))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 155, 11))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 155, 9))
|
||||
>Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 155, 11))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 155, 35))
|
||||
|
||||
|
||||
@@ -517,3 +517,19 @@ export class c {
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #31385
|
||||
|
||||
type Foo<T> = { [key: string]: { [K in keyof T]: K }[keyof T] };
|
||||
>Foo : Foo<T>
|
||||
>key : string
|
||||
|
||||
type Bar<T> = { [key: string]: { [K in keyof T]: [K] }[keyof T] };
|
||||
>Bar : Bar<T>
|
||||
>key : string
|
||||
|
||||
type Baz<T, Q extends Foo<T>> = { [K in keyof Q]: T[Q[K]] };
|
||||
>Baz : Baz<T, Q>
|
||||
|
||||
type Qux<T, Q extends Bar<T>> = { [K in keyof Q]: T[Q[K]["0"]] };
|
||||
>Qux : Qux<T, Q>
|
||||
|
||||
|
||||
@@ -147,3 +147,13 @@ export class c {
|
||||
this["a"] = "b";
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #31385
|
||||
|
||||
type Foo<T> = { [key: string]: { [K in keyof T]: K }[keyof T] };
|
||||
|
||||
type Bar<T> = { [key: string]: { [K in keyof T]: [K] }[keyof T] };
|
||||
|
||||
type Baz<T, Q extends Foo<T>> = { [K in keyof Q]: T[Q[K]] };
|
||||
|
||||
type Qux<T, Q extends Bar<T>> = { [K in keyof Q]: T[Q[K]["0"]] };
|
||||
|
||||
Reference in New Issue
Block a user