mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-17 13:48:46 -05:00
Revert "Always substitute indexed generic mapped type when getting constraint from indexed access" (#57202)
This commit is contained in:
committed by
GitHub
parent
3c9aea3ed1
commit
01527cece7
@@ -14230,7 +14230,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function getConstraintFromIndexedAccess(type: IndexedAccessType) {
|
||||
if (isMappedTypeGenericIndexedAccess(type) || isGenericMappedType(type.objectType)) {
|
||||
if (isMappedTypeGenericIndexedAccess(type)) {
|
||||
// For indexed access types of the form { [P in K]: E }[X], where K is non-generic and X is generic,
|
||||
// we substitute an instantiation of E where P is replaced with X.
|
||||
return substituteIndexedMappedType(type.objectType as MappedType, type.indexType);
|
||||
|
||||
@@ -1,28 +1,18 @@
|
||||
mappedTypeConstraints2.ts(10,11): error TS2322: Type 'Mapped2<K>[`get${K}`]' is not assignable to type '{ a: K; }'.
|
||||
Type '{ a: `get${K}`; }' is not assignable to type '{ a: K; }'.
|
||||
Types of property 'a' are incompatible.
|
||||
Type '`get${K}`' is not assignable to type 'K'.
|
||||
'`get${K}`' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'.
|
||||
Type '`get${string}`' is not assignable to type 'K'.
|
||||
'`get${string}`' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'.
|
||||
Type 'Mapped2<K>[`get${string}`]' is not assignable to type '{ a: K; }'.
|
||||
mappedTypeConstraints2.ts(16,11): error TS2322: Type 'Mapped3<K>[Uppercase<K>]' is not assignable to type '{ a: K; }'.
|
||||
Type '{ a: Uppercase<K>; }' is not assignable to type '{ a: K; }'.
|
||||
Types of property 'a' are incompatible.
|
||||
Type 'Uppercase<K>' is not assignable to type 'K'.
|
||||
'Uppercase<K>' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'.
|
||||
Type 'Uppercase<string>' is not assignable to type 'K'.
|
||||
'Uppercase<string>' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'.
|
||||
Type 'string' is not assignable to type 'K'.
|
||||
'string' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'.
|
||||
mappedTypeConstraints2.ts(25,57): error TS2322: Type 'Foo<T>[`get${T}`]' is not assignable to type 'T'.
|
||||
'Foo<T>[`get${T}`]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string'.
|
||||
Type '`get${T}`' is not assignable to type 'T'.
|
||||
'`get${T}`' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string'.
|
||||
Type '`get${string}`' is not assignable to type 'T'.
|
||||
'`get${string}`' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string'.
|
||||
Type 'Mapped3<K>[Uppercase<string>]' is not assignable to type '{ a: K; }'.
|
||||
Type 'Mapped3<K>[string]' is not assignable to type '{ a: K; }'.
|
||||
mappedTypeConstraints2.ts(42,7): error TS2322: Type 'Mapped6<K>[keyof Mapped6<K>]' is not assignable to type '`_${string}`'.
|
||||
Type 'Mapped6<K>[string] | Mapped6<K>[number] | Mapped6<K>[symbol]' is not assignable to type '`_${string}`'.
|
||||
Type 'Mapped6<K>[string]' is not assignable to type '`_${string}`'.
|
||||
mappedTypeConstraints2.ts(51,57): error TS2322: Type 'Foo<T>[`get${T}`]' is not assignable to type 'T'.
|
||||
'T' could be instantiated with an arbitrary type which could be unrelated to 'Foo<T>[`get${T}`]'.
|
||||
mappedTypeConstraints2.ts(82,9): error TS2322: Type 'ObjectWithUnderscoredKeys<K>[`_${K}`]' is not assignable to type 'true'.
|
||||
Type 'ObjectWithUnderscoredKeys<K>[`_${string}`]' is not assignable to type 'true'.
|
||||
|
||||
|
||||
==== mappedTypeConstraints2.ts (3 errors) ====
|
||||
==== mappedTypeConstraints2.ts (5 errors) ====
|
||||
type Mapped1<K extends string> = { [P in K]: { a: P } };
|
||||
|
||||
function f1<K extends string>(obj: Mapped1<K>, key: K) {
|
||||
@@ -35,12 +25,7 @@ mappedTypeConstraints2.ts(25,57): error TS2322: Type 'Foo<T>[`get${T}`]' is not
|
||||
const x: { a: K } = obj[key]; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'Mapped2<K>[`get${K}`]' is not assignable to type '{ a: K; }'.
|
||||
!!! error TS2322: Type '{ a: `get${K}`; }' is not assignable to type '{ a: K; }'.
|
||||
!!! error TS2322: Types of property 'a' are incompatible.
|
||||
!!! error TS2322: Type '`get${K}`' is not assignable to type 'K'.
|
||||
!!! error TS2322: '`get${K}`' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'.
|
||||
!!! error TS2322: Type '`get${string}`' is not assignable to type 'K'.
|
||||
!!! error TS2322: '`get${string}`' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'.
|
||||
!!! error TS2322: Type 'Mapped2<K>[`get${string}`]' is not assignable to type '{ a: K; }'.
|
||||
}
|
||||
|
||||
type Mapped3<K extends string> = { [P in K as Uppercase<P>]: { a: P } };
|
||||
@@ -49,14 +34,38 @@ mappedTypeConstraints2.ts(25,57): error TS2322: Type 'Foo<T>[`get${T}`]' is not
|
||||
const x: { a: K } = obj[key]; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'Mapped3<K>[Uppercase<K>]' is not assignable to type '{ a: K; }'.
|
||||
!!! error TS2322: Type '{ a: Uppercase<K>; }' is not assignable to type '{ a: K; }'.
|
||||
!!! error TS2322: Types of property 'a' are incompatible.
|
||||
!!! error TS2322: Type 'Uppercase<K>' is not assignable to type 'K'.
|
||||
!!! error TS2322: 'Uppercase<K>' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'.
|
||||
!!! error TS2322: Type 'Uppercase<string>' is not assignable to type 'K'.
|
||||
!!! error TS2322: 'Uppercase<string>' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'K'.
|
||||
!!! error TS2322: 'string' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'.
|
||||
!!! error TS2322: Type 'Mapped3<K>[Uppercase<string>]' is not assignable to type '{ a: K; }'.
|
||||
!!! error TS2322: Type 'Mapped3<K>[string]' is not assignable to type '{ a: K; }'.
|
||||
}
|
||||
|
||||
type Mapped4<K extends `_${string}`> = {
|
||||
[P in K]: P;
|
||||
};
|
||||
|
||||
function f4<K extends `_${string}`>(obj: Mapped4<K>, key: keyof Mapped4<K>) {
|
||||
let s: `_${string}` = obj[key];
|
||||
}
|
||||
|
||||
type Mapped5<K extends string> = {
|
||||
[P in K as P extends `_${string}` ? P : never]: P;
|
||||
};
|
||||
|
||||
function f5<K extends string>(obj: Mapped5<K>, key: keyof Mapped5<K>) {
|
||||
let s: `_${string}` = obj[key];
|
||||
}
|
||||
|
||||
// repro from #53066#issuecomment-1913384757
|
||||
|
||||
type Mapped6<K extends string> = {
|
||||
[P in K as `_${P}`]: P;
|
||||
};
|
||||
|
||||
function f6<K extends string>(obj: Mapped6<K>, key: keyof Mapped6<K>) {
|
||||
let s: `_${string}` = obj[key]; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'Mapped6<K>[keyof Mapped6<K>]' is not assignable to type '`_${string}`'.
|
||||
!!! error TS2322: Type 'Mapped6<K>[string] | Mapped6<K>[number] | Mapped6<K>[symbol]' is not assignable to type '`_${string}`'.
|
||||
!!! error TS2322: Type 'Mapped6<K>[string]' is not assignable to type '`_${string}`'.
|
||||
}
|
||||
|
||||
// Repro from #47794
|
||||
@@ -68,11 +77,7 @@ mappedTypeConstraints2.ts(25,57): error TS2322: Type 'Foo<T>[`get${T}`]' is not
|
||||
const get = <T extends string>(t: T, foo: Foo<T>): T => foo[`get${t}`]; // Type 'Foo<T>[`get${T}`]' is not assignable to type 'T'
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'Foo<T>[`get${T}`]' is not assignable to type 'T'.
|
||||
!!! error TS2322: 'Foo<T>[`get${T}`]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string'.
|
||||
!!! error TS2322: Type '`get${T}`' is not assignable to type 'T'.
|
||||
!!! error TS2322: '`get${T}`' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string'.
|
||||
!!! error TS2322: Type '`get${string}`' is not assignable to type 'T'.
|
||||
!!! error TS2322: '`get${string}`' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string'.
|
||||
!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Foo<T>[`get${T}`]'.
|
||||
|
||||
// Repro from #48626
|
||||
|
||||
@@ -103,6 +108,9 @@ mappedTypeConstraints2.ts(25,57): error TS2322: Type 'Foo<T>[`get${T}`]' is not
|
||||
};
|
||||
|
||||
function genericTest<K extends string>(objectWithUnderscoredKeys: ObjectWithUnderscoredKeys<K>, key: K) {
|
||||
const shouldBeTrue: true = objectWithUnderscoredKeys[`_${key}`];
|
||||
const shouldBeTrue: true = objectWithUnderscoredKeys[`_${key}`]; // assignability fails here, but ideally should not
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'ObjectWithUnderscoredKeys<K>[`_${K}`]' is not assignable to type 'true'.
|
||||
!!! error TS2322: Type 'ObjectWithUnderscoredKeys<K>[`_${string}`]' is not assignable to type 'true'.
|
||||
}
|
||||
|
||||
@@ -19,6 +19,32 @@ function f3<K extends string>(obj: Mapped3<K>, key: Uppercase<K>) {
|
||||
const x: { a: K } = obj[key]; // Error
|
||||
}
|
||||
|
||||
type Mapped4<K extends `_${string}`> = {
|
||||
[P in K]: P;
|
||||
};
|
||||
|
||||
function f4<K extends `_${string}`>(obj: Mapped4<K>, key: keyof Mapped4<K>) {
|
||||
let s: `_${string}` = obj[key];
|
||||
}
|
||||
|
||||
type Mapped5<K extends string> = {
|
||||
[P in K as P extends `_${string}` ? P : never]: P;
|
||||
};
|
||||
|
||||
function f5<K extends string>(obj: Mapped5<K>, key: keyof Mapped5<K>) {
|
||||
let s: `_${string}` = obj[key];
|
||||
}
|
||||
|
||||
// repro from #53066#issuecomment-1913384757
|
||||
|
||||
type Mapped6<K extends string> = {
|
||||
[P in K as `_${P}`]: P;
|
||||
};
|
||||
|
||||
function f6<K extends string>(obj: Mapped6<K>, key: keyof Mapped6<K>) {
|
||||
let s: `_${string}` = obj[key]; // Error
|
||||
}
|
||||
|
||||
// Repro from #47794
|
||||
|
||||
type Foo<T extends string> = {
|
||||
@@ -56,7 +82,7 @@ type ObjectWithUnderscoredKeys<K extends string> = {
|
||||
};
|
||||
|
||||
function genericTest<K extends string>(objectWithUnderscoredKeys: ObjectWithUnderscoredKeys<K>, key: K) {
|
||||
const shouldBeTrue: true = objectWithUnderscoredKeys[`_${key}`];
|
||||
const shouldBeTrue: true = objectWithUnderscoredKeys[`_${key}`]; // assignability fails here, but ideally should not
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +97,15 @@ function f2(obj, key) {
|
||||
function f3(obj, key) {
|
||||
const x = obj[key]; // Error
|
||||
}
|
||||
function f4(obj, key) {
|
||||
let s = obj[key];
|
||||
}
|
||||
function f5(obj, key) {
|
||||
let s = obj[key];
|
||||
}
|
||||
function f6(obj, key) {
|
||||
let s = obj[key]; // Error
|
||||
}
|
||||
const get = (t, foo) => foo[`get${t}`]; // Type 'Foo<T>[`get${T}`]' is not assignable to type 'T'
|
||||
function validate(obj, bounds) {
|
||||
for (const [key, val] of Object.entries(obj)) {
|
||||
@@ -84,7 +119,7 @@ function validate(obj, bounds) {
|
||||
return true;
|
||||
}
|
||||
function genericTest(objectWithUnderscoredKeys, key) {
|
||||
const shouldBeTrue = objectWithUnderscoredKeys[`_${key}`];
|
||||
const shouldBeTrue = objectWithUnderscoredKeys[`_${key}`]; // assignability fails here, but ideally should not
|
||||
}
|
||||
|
||||
|
||||
@@ -107,6 +142,18 @@ type Mapped3<K extends string> = {
|
||||
};
|
||||
};
|
||||
declare function f3<K extends string>(obj: Mapped3<K>, key: Uppercase<K>): void;
|
||||
type Mapped4<K extends `_${string}`> = {
|
||||
[P in K]: P;
|
||||
};
|
||||
declare function f4<K extends `_${string}`>(obj: Mapped4<K>, key: keyof Mapped4<K>): void;
|
||||
type Mapped5<K extends string> = {
|
||||
[P in K as P extends `_${string}` ? P : never]: P;
|
||||
};
|
||||
declare function f5<K extends string>(obj: Mapped5<K>, key: keyof Mapped5<K>): void;
|
||||
type Mapped6<K extends string> = {
|
||||
[P in K as `_${P}`]: P;
|
||||
};
|
||||
declare function f6<K extends string>(obj: Mapped6<K>, key: keyof Mapped6<K>): void;
|
||||
type Foo<T extends string> = {
|
||||
[RemappedT in T as `get${RemappedT}`]: RemappedT;
|
||||
};
|
||||
|
||||
@@ -80,94 +80,180 @@ function f3<K extends string>(obj: Mapped3<K>, key: Uppercase<K>) {
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 14, 46))
|
||||
}
|
||||
|
||||
type Mapped4<K extends `_${string}`> = {
|
||||
>Mapped4 : Symbol(Mapped4, Decl(mappedTypeConstraints2.ts, 16, 1))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 18, 13))
|
||||
|
||||
[P in K]: P;
|
||||
>P : Symbol(P, Decl(mappedTypeConstraints2.ts, 19, 3))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 18, 13))
|
||||
>P : Symbol(P, Decl(mappedTypeConstraints2.ts, 19, 3))
|
||||
|
||||
};
|
||||
|
||||
function f4<K extends `_${string}`>(obj: Mapped4<K>, key: keyof Mapped4<K>) {
|
||||
>f4 : Symbol(f4, Decl(mappedTypeConstraints2.ts, 20, 2))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 22, 12))
|
||||
>obj : Symbol(obj, Decl(mappedTypeConstraints2.ts, 22, 36))
|
||||
>Mapped4 : Symbol(Mapped4, Decl(mappedTypeConstraints2.ts, 16, 1))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 22, 12))
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 22, 52))
|
||||
>Mapped4 : Symbol(Mapped4, Decl(mappedTypeConstraints2.ts, 16, 1))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 22, 12))
|
||||
|
||||
let s: `_${string}` = obj[key];
|
||||
>s : Symbol(s, Decl(mappedTypeConstraints2.ts, 23, 5))
|
||||
>obj : Symbol(obj, Decl(mappedTypeConstraints2.ts, 22, 36))
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 22, 52))
|
||||
}
|
||||
|
||||
type Mapped5<K extends string> = {
|
||||
>Mapped5 : Symbol(Mapped5, Decl(mappedTypeConstraints2.ts, 24, 1))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 26, 13))
|
||||
|
||||
[P in K as P extends `_${string}` ? P : never]: P;
|
||||
>P : Symbol(P, Decl(mappedTypeConstraints2.ts, 27, 3))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 26, 13))
|
||||
>P : Symbol(P, Decl(mappedTypeConstraints2.ts, 27, 3))
|
||||
>P : Symbol(P, Decl(mappedTypeConstraints2.ts, 27, 3))
|
||||
>P : Symbol(P, Decl(mappedTypeConstraints2.ts, 27, 3))
|
||||
|
||||
};
|
||||
|
||||
function f5<K extends string>(obj: Mapped5<K>, key: keyof Mapped5<K>) {
|
||||
>f5 : Symbol(f5, Decl(mappedTypeConstraints2.ts, 28, 2))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 30, 12))
|
||||
>obj : Symbol(obj, Decl(mappedTypeConstraints2.ts, 30, 30))
|
||||
>Mapped5 : Symbol(Mapped5, Decl(mappedTypeConstraints2.ts, 24, 1))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 30, 12))
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 30, 46))
|
||||
>Mapped5 : Symbol(Mapped5, Decl(mappedTypeConstraints2.ts, 24, 1))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 30, 12))
|
||||
|
||||
let s: `_${string}` = obj[key];
|
||||
>s : Symbol(s, Decl(mappedTypeConstraints2.ts, 31, 5))
|
||||
>obj : Symbol(obj, Decl(mappedTypeConstraints2.ts, 30, 30))
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 30, 46))
|
||||
}
|
||||
|
||||
// repro from #53066#issuecomment-1913384757
|
||||
|
||||
type Mapped6<K extends string> = {
|
||||
>Mapped6 : Symbol(Mapped6, Decl(mappedTypeConstraints2.ts, 32, 1))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 36, 13))
|
||||
|
||||
[P in K as `_${P}`]: P;
|
||||
>P : Symbol(P, Decl(mappedTypeConstraints2.ts, 37, 3))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 36, 13))
|
||||
>P : Symbol(P, Decl(mappedTypeConstraints2.ts, 37, 3))
|
||||
>P : Symbol(P, Decl(mappedTypeConstraints2.ts, 37, 3))
|
||||
|
||||
};
|
||||
|
||||
function f6<K extends string>(obj: Mapped6<K>, key: keyof Mapped6<K>) {
|
||||
>f6 : Symbol(f6, Decl(mappedTypeConstraints2.ts, 38, 2))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 40, 12))
|
||||
>obj : Symbol(obj, Decl(mappedTypeConstraints2.ts, 40, 30))
|
||||
>Mapped6 : Symbol(Mapped6, Decl(mappedTypeConstraints2.ts, 32, 1))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 40, 12))
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 40, 46))
|
||||
>Mapped6 : Symbol(Mapped6, Decl(mappedTypeConstraints2.ts, 32, 1))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 40, 12))
|
||||
|
||||
let s: `_${string}` = obj[key]; // Error
|
||||
>s : Symbol(s, Decl(mappedTypeConstraints2.ts, 41, 5))
|
||||
>obj : Symbol(obj, Decl(mappedTypeConstraints2.ts, 40, 30))
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 40, 46))
|
||||
}
|
||||
|
||||
// Repro from #47794
|
||||
|
||||
type Foo<T extends string> = {
|
||||
>Foo : Symbol(Foo, Decl(mappedTypeConstraints2.ts, 16, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 20, 9))
|
||||
>Foo : Symbol(Foo, Decl(mappedTypeConstraints2.ts, 42, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 46, 9))
|
||||
|
||||
[RemappedT in T as `get${RemappedT}`]: RemappedT;
|
||||
>RemappedT : Symbol(RemappedT, Decl(mappedTypeConstraints2.ts, 21, 5))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 20, 9))
|
||||
>RemappedT : Symbol(RemappedT, Decl(mappedTypeConstraints2.ts, 21, 5))
|
||||
>RemappedT : Symbol(RemappedT, Decl(mappedTypeConstraints2.ts, 21, 5))
|
||||
>RemappedT : Symbol(RemappedT, Decl(mappedTypeConstraints2.ts, 47, 5))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 46, 9))
|
||||
>RemappedT : Symbol(RemappedT, Decl(mappedTypeConstraints2.ts, 47, 5))
|
||||
>RemappedT : Symbol(RemappedT, Decl(mappedTypeConstraints2.ts, 47, 5))
|
||||
|
||||
};
|
||||
|
||||
const get = <T extends string>(t: T, foo: Foo<T>): T => foo[`get${t}`]; // Type 'Foo<T>[`get${T}`]' is not assignable to type 'T'
|
||||
>get : Symbol(get, Decl(mappedTypeConstraints2.ts, 24, 5))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 24, 13))
|
||||
>t : Symbol(t, Decl(mappedTypeConstraints2.ts, 24, 31))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 24, 13))
|
||||
>foo : Symbol(foo, Decl(mappedTypeConstraints2.ts, 24, 36))
|
||||
>Foo : Symbol(Foo, Decl(mappedTypeConstraints2.ts, 16, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 24, 13))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 24, 13))
|
||||
>foo : Symbol(foo, Decl(mappedTypeConstraints2.ts, 24, 36))
|
||||
>t : Symbol(t, Decl(mappedTypeConstraints2.ts, 24, 31))
|
||||
>get : Symbol(get, Decl(mappedTypeConstraints2.ts, 50, 5))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 50, 13))
|
||||
>t : Symbol(t, Decl(mappedTypeConstraints2.ts, 50, 31))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 50, 13))
|
||||
>foo : Symbol(foo, Decl(mappedTypeConstraints2.ts, 50, 36))
|
||||
>Foo : Symbol(Foo, Decl(mappedTypeConstraints2.ts, 42, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 50, 13))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 50, 13))
|
||||
>foo : Symbol(foo, Decl(mappedTypeConstraints2.ts, 50, 36))
|
||||
>t : Symbol(t, Decl(mappedTypeConstraints2.ts, 50, 31))
|
||||
|
||||
// Repro from #48626
|
||||
|
||||
interface Bounds {
|
||||
>Bounds : Symbol(Bounds, Decl(mappedTypeConstraints2.ts, 24, 71))
|
||||
>Bounds : Symbol(Bounds, Decl(mappedTypeConstraints2.ts, 50, 71))
|
||||
|
||||
min: number;
|
||||
>min : Symbol(Bounds.min, Decl(mappedTypeConstraints2.ts, 28, 18))
|
||||
>min : Symbol(Bounds.min, Decl(mappedTypeConstraints2.ts, 54, 18))
|
||||
|
||||
max: number;
|
||||
>max : Symbol(Bounds.max, Decl(mappedTypeConstraints2.ts, 29, 16))
|
||||
>max : Symbol(Bounds.max, Decl(mappedTypeConstraints2.ts, 55, 16))
|
||||
}
|
||||
|
||||
type NumericBoundsOf<T> = {
|
||||
>NumericBoundsOf : Symbol(NumericBoundsOf, Decl(mappedTypeConstraints2.ts, 31, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 33, 21))
|
||||
>NumericBoundsOf : Symbol(NumericBoundsOf, Decl(mappedTypeConstraints2.ts, 57, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 59, 21))
|
||||
|
||||
[K in keyof T as T[K] extends number | undefined ? K : never]: Bounds;
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 34, 5))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 33, 21))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 33, 21))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 34, 5))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 34, 5))
|
||||
>Bounds : Symbol(Bounds, Decl(mappedTypeConstraints2.ts, 24, 71))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 60, 5))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 59, 21))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 59, 21))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 60, 5))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 60, 5))
|
||||
>Bounds : Symbol(Bounds, Decl(mappedTypeConstraints2.ts, 50, 71))
|
||||
}
|
||||
|
||||
function validate<T extends object>(obj: T, bounds: NumericBoundsOf<T>) {
|
||||
>validate : Symbol(validate, Decl(mappedTypeConstraints2.ts, 35, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 37, 18))
|
||||
>obj : Symbol(obj, Decl(mappedTypeConstraints2.ts, 37, 36))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 37, 18))
|
||||
>bounds : Symbol(bounds, Decl(mappedTypeConstraints2.ts, 37, 43))
|
||||
>NumericBoundsOf : Symbol(NumericBoundsOf, Decl(mappedTypeConstraints2.ts, 31, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 37, 18))
|
||||
>validate : Symbol(validate, Decl(mappedTypeConstraints2.ts, 61, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 63, 18))
|
||||
>obj : Symbol(obj, Decl(mappedTypeConstraints2.ts, 63, 36))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 63, 18))
|
||||
>bounds : Symbol(bounds, Decl(mappedTypeConstraints2.ts, 63, 43))
|
||||
>NumericBoundsOf : Symbol(NumericBoundsOf, Decl(mappedTypeConstraints2.ts, 57, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 63, 18))
|
||||
|
||||
for (const [key, val] of Object.entries(obj)) {
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 38, 16))
|
||||
>val : Symbol(val, Decl(mappedTypeConstraints2.ts, 38, 20))
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 64, 16))
|
||||
>val : Symbol(val, Decl(mappedTypeConstraints2.ts, 64, 20))
|
||||
>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --))
|
||||
>obj : Symbol(obj, Decl(mappedTypeConstraints2.ts, 37, 36))
|
||||
>obj : Symbol(obj, Decl(mappedTypeConstraints2.ts, 63, 36))
|
||||
|
||||
const boundsForKey = bounds[key as keyof NumericBoundsOf<T>];
|
||||
>boundsForKey : Symbol(boundsForKey, Decl(mappedTypeConstraints2.ts, 39, 13))
|
||||
>bounds : Symbol(bounds, Decl(mappedTypeConstraints2.ts, 37, 43))
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 38, 16))
|
||||
>NumericBoundsOf : Symbol(NumericBoundsOf, Decl(mappedTypeConstraints2.ts, 31, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 37, 18))
|
||||
>boundsForKey : Symbol(boundsForKey, Decl(mappedTypeConstraints2.ts, 65, 13))
|
||||
>bounds : Symbol(bounds, Decl(mappedTypeConstraints2.ts, 63, 43))
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 64, 16))
|
||||
>NumericBoundsOf : Symbol(NumericBoundsOf, Decl(mappedTypeConstraints2.ts, 57, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeConstraints2.ts, 63, 18))
|
||||
|
||||
if (boundsForKey) {
|
||||
>boundsForKey : Symbol(boundsForKey, Decl(mappedTypeConstraints2.ts, 39, 13))
|
||||
>boundsForKey : Symbol(boundsForKey, Decl(mappedTypeConstraints2.ts, 65, 13))
|
||||
|
||||
const { min, max } = boundsForKey;
|
||||
>min : Symbol(min, Decl(mappedTypeConstraints2.ts, 41, 19))
|
||||
>max : Symbol(max, Decl(mappedTypeConstraints2.ts, 41, 24))
|
||||
>boundsForKey : Symbol(boundsForKey, Decl(mappedTypeConstraints2.ts, 39, 13))
|
||||
>min : Symbol(min, Decl(mappedTypeConstraints2.ts, 67, 19))
|
||||
>max : Symbol(max, Decl(mappedTypeConstraints2.ts, 67, 24))
|
||||
>boundsForKey : Symbol(boundsForKey, Decl(mappedTypeConstraints2.ts, 65, 13))
|
||||
|
||||
if (min > val || max < val) return false;
|
||||
>min : Symbol(min, Decl(mappedTypeConstraints2.ts, 41, 19))
|
||||
>val : Symbol(val, Decl(mappedTypeConstraints2.ts, 38, 20))
|
||||
>max : Symbol(max, Decl(mappedTypeConstraints2.ts, 41, 24))
|
||||
>val : Symbol(val, Decl(mappedTypeConstraints2.ts, 38, 20))
|
||||
>min : Symbol(min, Decl(mappedTypeConstraints2.ts, 67, 19))
|
||||
>val : Symbol(val, Decl(mappedTypeConstraints2.ts, 64, 20))
|
||||
>max : Symbol(max, Decl(mappedTypeConstraints2.ts, 67, 24))
|
||||
>val : Symbol(val, Decl(mappedTypeConstraints2.ts, 64, 20))
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -176,28 +262,28 @@ function validate<T extends object>(obj: T, bounds: NumericBoundsOf<T>) {
|
||||
// repro from #50030
|
||||
|
||||
type ObjectWithUnderscoredKeys<K extends string> = {
|
||||
>ObjectWithUnderscoredKeys : Symbol(ObjectWithUnderscoredKeys, Decl(mappedTypeConstraints2.ts, 46, 1))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 50, 31))
|
||||
>ObjectWithUnderscoredKeys : Symbol(ObjectWithUnderscoredKeys, Decl(mappedTypeConstraints2.ts, 72, 1))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 76, 31))
|
||||
|
||||
[k in K as `_${k}`]: true;
|
||||
>k : Symbol(k, Decl(mappedTypeConstraints2.ts, 51, 5))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 50, 31))
|
||||
>k : Symbol(k, Decl(mappedTypeConstraints2.ts, 51, 5))
|
||||
>k : Symbol(k, Decl(mappedTypeConstraints2.ts, 77, 5))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 76, 31))
|
||||
>k : Symbol(k, Decl(mappedTypeConstraints2.ts, 77, 5))
|
||||
|
||||
};
|
||||
|
||||
function genericTest<K extends string>(objectWithUnderscoredKeys: ObjectWithUnderscoredKeys<K>, key: K) {
|
||||
>genericTest : Symbol(genericTest, Decl(mappedTypeConstraints2.ts, 52, 2))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 54, 21))
|
||||
>objectWithUnderscoredKeys : Symbol(objectWithUnderscoredKeys, Decl(mappedTypeConstraints2.ts, 54, 39))
|
||||
>ObjectWithUnderscoredKeys : Symbol(ObjectWithUnderscoredKeys, Decl(mappedTypeConstraints2.ts, 46, 1))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 54, 21))
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 54, 95))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 54, 21))
|
||||
>genericTest : Symbol(genericTest, Decl(mappedTypeConstraints2.ts, 78, 2))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 80, 21))
|
||||
>objectWithUnderscoredKeys : Symbol(objectWithUnderscoredKeys, Decl(mappedTypeConstraints2.ts, 80, 39))
|
||||
>ObjectWithUnderscoredKeys : Symbol(ObjectWithUnderscoredKeys, Decl(mappedTypeConstraints2.ts, 72, 1))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 80, 21))
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 80, 95))
|
||||
>K : Symbol(K, Decl(mappedTypeConstraints2.ts, 80, 21))
|
||||
|
||||
const shouldBeTrue: true = objectWithUnderscoredKeys[`_${key}`];
|
||||
>shouldBeTrue : Symbol(shouldBeTrue, Decl(mappedTypeConstraints2.ts, 55, 7))
|
||||
>objectWithUnderscoredKeys : Symbol(objectWithUnderscoredKeys, Decl(mappedTypeConstraints2.ts, 54, 39))
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 54, 95))
|
||||
const shouldBeTrue: true = objectWithUnderscoredKeys[`_${key}`]; // assignability fails here, but ideally should not
|
||||
>shouldBeTrue : Symbol(shouldBeTrue, Decl(mappedTypeConstraints2.ts, 81, 7))
|
||||
>objectWithUnderscoredKeys : Symbol(objectWithUnderscoredKeys, Decl(mappedTypeConstraints2.ts, 80, 39))
|
||||
>key : Symbol(key, Decl(mappedTypeConstraints2.ts, 80, 95))
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,62 @@ function f3<K extends string>(obj: Mapped3<K>, key: Uppercase<K>) {
|
||||
>key : Uppercase<K>
|
||||
}
|
||||
|
||||
type Mapped4<K extends `_${string}`> = {
|
||||
>Mapped4 : Mapped4<K>
|
||||
|
||||
[P in K]: P;
|
||||
};
|
||||
|
||||
function f4<K extends `_${string}`>(obj: Mapped4<K>, key: keyof Mapped4<K>) {
|
||||
>f4 : <K extends `_${string}`>(obj: Mapped4<K>, key: keyof Mapped4<K>) => void
|
||||
>obj : Mapped4<K>
|
||||
>key : K
|
||||
|
||||
let s: `_${string}` = obj[key];
|
||||
>s : `_${string}`
|
||||
>obj[key] : Mapped4<K>[K]
|
||||
>obj : Mapped4<K>
|
||||
>key : K
|
||||
}
|
||||
|
||||
type Mapped5<K extends string> = {
|
||||
>Mapped5 : Mapped5<K>
|
||||
|
||||
[P in K as P extends `_${string}` ? P : never]: P;
|
||||
};
|
||||
|
||||
function f5<K extends string>(obj: Mapped5<K>, key: keyof Mapped5<K>) {
|
||||
>f5 : <K extends string>(obj: Mapped5<K>, key: keyof Mapped5<K>) => void
|
||||
>obj : Mapped5<K>
|
||||
>key : K extends `_${string}` ? K : never
|
||||
|
||||
let s: `_${string}` = obj[key];
|
||||
>s : `_${string}`
|
||||
>obj[key] : Mapped5<K>[K extends `_${string}` ? K : never]
|
||||
>obj : Mapped5<K>
|
||||
>key : K extends `_${string}` ? K : never
|
||||
}
|
||||
|
||||
// repro from #53066#issuecomment-1913384757
|
||||
|
||||
type Mapped6<K extends string> = {
|
||||
>Mapped6 : Mapped6<K>
|
||||
|
||||
[P in K as `_${P}`]: P;
|
||||
};
|
||||
|
||||
function f6<K extends string>(obj: Mapped6<K>, key: keyof Mapped6<K>) {
|
||||
>f6 : <K extends string>(obj: Mapped6<K>, key: keyof Mapped6<K>) => void
|
||||
>obj : Mapped6<K>
|
||||
>key : keyof Mapped6<K>
|
||||
|
||||
let s: `_${string}` = obj[key]; // Error
|
||||
>s : `_${string}`
|
||||
>obj[key] : Mapped6<K>[keyof Mapped6<K>]
|
||||
>obj : Mapped6<K>
|
||||
>key : keyof Mapped6<K>
|
||||
}
|
||||
|
||||
// Repro from #47794
|
||||
|
||||
type Foo<T extends string> = {
|
||||
@@ -145,7 +201,7 @@ function genericTest<K extends string>(objectWithUnderscoredKeys: ObjectWithUnde
|
||||
>objectWithUnderscoredKeys : ObjectWithUnderscoredKeys<K>
|
||||
>key : K
|
||||
|
||||
const shouldBeTrue: true = objectWithUnderscoredKeys[`_${key}`];
|
||||
const shouldBeTrue: true = objectWithUnderscoredKeys[`_${key}`]; // assignability fails here, but ideally should not
|
||||
>shouldBeTrue : true
|
||||
>true : true
|
||||
>objectWithUnderscoredKeys[`_${key}`] : ObjectWithUnderscoredKeys<K>[`_${K}`]
|
||||
|
||||
@@ -20,6 +20,32 @@ function f3<K extends string>(obj: Mapped3<K>, key: Uppercase<K>) {
|
||||
const x: { a: K } = obj[key]; // Error
|
||||
}
|
||||
|
||||
type Mapped4<K extends `_${string}`> = {
|
||||
[P in K]: P;
|
||||
};
|
||||
|
||||
function f4<K extends `_${string}`>(obj: Mapped4<K>, key: keyof Mapped4<K>) {
|
||||
let s: `_${string}` = obj[key];
|
||||
}
|
||||
|
||||
type Mapped5<K extends string> = {
|
||||
[P in K as P extends `_${string}` ? P : never]: P;
|
||||
};
|
||||
|
||||
function f5<K extends string>(obj: Mapped5<K>, key: keyof Mapped5<K>) {
|
||||
let s: `_${string}` = obj[key];
|
||||
}
|
||||
|
||||
// repro from #53066#issuecomment-1913384757
|
||||
|
||||
type Mapped6<K extends string> = {
|
||||
[P in K as `_${P}`]: P;
|
||||
};
|
||||
|
||||
function f6<K extends string>(obj: Mapped6<K>, key: keyof Mapped6<K>) {
|
||||
let s: `_${string}` = obj[key]; // Error
|
||||
}
|
||||
|
||||
// Repro from #47794
|
||||
|
||||
type Foo<T extends string> = {
|
||||
@@ -57,5 +83,5 @@ type ObjectWithUnderscoredKeys<K extends string> = {
|
||||
};
|
||||
|
||||
function genericTest<K extends string>(objectWithUnderscoredKeys: ObjectWithUnderscoredKeys<K>, key: K) {
|
||||
const shouldBeTrue: true = objectWithUnderscoredKeys[`_${key}`];
|
||||
const shouldBeTrue: true = objectWithUnderscoredKeys[`_${key}`]; // assignability fails here, but ideally should not
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user