1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
=== tests/cases/conformance/types/mapped/mappedTypeConstraints2.ts ===
type Mapped1<K extends string> = { [P in K]: { a: P } };
>Mapped1 : Mapped1<K>
>a : P
function f1<K extends string>(obj: Mapped1<K>, key: K) {
>f1 : <K extends string>(obj: Mapped1<K>, key: K) => void
>obj : Mapped1<K>
>key : K
const x: { a: K } = obj[key];
>x : { a: K; }
>a : K
>obj[key] : Mapped1<K>[K]
>obj : Mapped1<K>
>key : K
}
type Mapped2<K extends string> = { [P in K as `get${P}`]: { a: P } };
>Mapped2 : Mapped2<K>
>a : P
function f2<K extends string>(obj: Mapped2<K>, key: `get${K}`) {
>f2 : <K extends string>(obj: Mapped2<K>, key: `get${K}`) => void
>obj : Mapped2<K>
>key : `get${K}`
const x: { a: K } = obj[key]; // Error
>x : { a: K; }
>a : K
>obj[key] : Mapped2<K>[`get${K}`]
>obj : Mapped2<K>
>key : `get${K}`
}
type Mapped3<K extends string> = { [P in K as Uppercase<P>]: { a: P } };
>Mapped3 : Mapped3<K>
>a : P
function f3<K extends string>(obj: Mapped3<K>, key: Uppercase<K>) {
>f3 : <K extends string>(obj: Mapped3<K>, key: Uppercase<K>) => void
>obj : Mapped3<K>
>key : Uppercase<K>
const x: { a: K } = obj[key]; // Error
>x : { a: K; }
>a : K
>obj[key] : Mapped3<K>[Uppercase<K>]
>obj : Mapped3<K>
>key : Uppercase<K>
}
// Repro from #47794
type Foo<T extends string> = {
>Foo : Foo<T>
[RemappedT in T as `get${RemappedT}`]: RemappedT;
};
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 : <T extends string>(t: T, foo: Foo<T>) => T
><T extends string>(t: T, foo: Foo<T>): T => foo[`get${t}`] : <T extends string>(t: T, foo: Foo<T>) => T
>t : T
>foo : Foo<T>
>foo[`get${t}`] : Foo<T>[`get${T}`]
>foo : Foo<T>
>`get${t}` : `get${T}`
>t : T
// Repro from #48626
interface Bounds {
min: number;
>min : number
max: number;
>max : number
}
type NumericBoundsOf<T> = {
>NumericBoundsOf : NumericBoundsOf<T>
[K in keyof T as T[K] extends number | undefined ? K : never]: Bounds;
}
function validate<T extends object>(obj: T, bounds: NumericBoundsOf<T>) {
>validate : <T extends object>(obj: T, bounds: NumericBoundsOf<T>) => boolean
>obj : T
>bounds : NumericBoundsOf<T>
for (const [key, val] of Object.entries(obj)) {
>key : string
>val : any
>Object.entries(obj) : [string, any][]
>Object.entries : { <T>(o: { [s: string]: T; } | ArrayLike<T>): [string, T][]; (o: {}): [string, any][]; }
>Object : ObjectConstructor
>entries : { <T>(o: { [s: string]: T; } | ArrayLike<T>): [string, T][]; (o: {}): [string, any][]; }
>obj : T
const boundsForKey = bounds[key as keyof NumericBoundsOf<T>];
>boundsForKey : NumericBoundsOf<T>[keyof NumericBoundsOf<T>]
>bounds[key as keyof NumericBoundsOf<T>] : NumericBoundsOf<T>[keyof NumericBoundsOf<T>]
>bounds : NumericBoundsOf<T>
>key as keyof NumericBoundsOf<T> : keyof NumericBoundsOf<T>
>key : string
if (boundsForKey) {
>boundsForKey : NumericBoundsOf<T>[keyof NumericBoundsOf<T>]
const { min, max } = boundsForKey;
>min : number
>max : number
>boundsForKey : NumericBoundsOf<T>[keyof NumericBoundsOf<T>]
if (min > val || max < val) return false;
>min > val || max < val : boolean
>min > val : boolean
>min : number
>val : any
>max < val : boolean
>max : number
>val : any
>false : false
}
}
return true;
>true : true
}
|