=== tests/cases/conformance/types/mapped/mappedTypeAsClauses.ts === // Mapped type 'as N' clauses type Getters = { [P in keyof T & string as `get${Capitalize

}`]: () => T[P] }; >Getters : Getters type TG1 = Getters<{ foo: string, bar: number, baz: { z: boolean } }>; >TG1 : TG1 >foo : string >bar : number >baz : { z: boolean; } >z : boolean // Mapped type with 'as N' clause has no constraint on 'in T' clause type PropDef = { name: K, type: T }; >PropDef : PropDef >name : K >type : T type TypeFromDefs> = { [P in T as P['name']]: P['type'] }; >TypeFromDefs : TypeFromDefs type TP1 = TypeFromDefs<{ name: 'a', type: string } | { name: 'b', type: number } | { name: 'a', type: boolean }>; >TP1 : TP1 >name : "a" >type : string >name : "b" >type : number >name : "a" >type : boolean // No array or tuple type mapping when 'as N' clause present type TA1 = Getters; >TA1 : TA1 type TA2 = Getters<[number, boolean]>; >TA2 : TA2 // Filtering using 'as N' clause type Methods = { [P in keyof T as T[P] extends Function ? P : never]: T[P] }; >Methods : Methods type TM1 = Methods<{ foo(): number, bar(x: string): boolean, baz: string | number }>; >TM1 : Methods<{ foo(): number; bar(x: string): boolean; baz: string | number; }> >foo : () => number >bar : (x: string) => boolean >x : string >baz : string | number // Mapping to multiple names using 'as N' clause type DoubleProp = { [P in keyof T & string as `${P}1` | `${P}2`]: T[P] } >DoubleProp : DoubleProp type TD1 = DoubleProp<{ a: string, b: number }>; // { a1: string, a2: string, b1: number, b2: number } >TD1 : TD1 >a : string >b : number type TD2 = keyof TD1; // 'a1' | 'a2' | 'b1' | 'b2' >TD2 : "a1" | "a2" | "b1" | "b2" type TD3 = keyof DoubleProp; // `${keyof U & string}1` | `${keyof U & string}2` >TD3 : `${keyof U & string}1` | `${keyof U & string}2` // Repro from #40619 type Lazyify = { >Lazyify : Lazyify [K in keyof T as `get${Capitalize}`]: () => T[K] }; interface Person { readonly name: string; >name : string age: number; >age : number location?: string; >location : string | undefined } type LazyPerson = Lazyify; >LazyPerson : Lazyify // Repro from #40833 type Example = {foo: string, bar: number}; >Example : Example >foo : string >bar : number type PickByValueType = { >PickByValueType : PickByValueType [K in keyof T as T[K] extends U ? K : never]: T[K] }; type T1 = PickByValueType; >T1 : PickByValueType const e1: T1 = { >e1 : PickByValueType >{ foo: "hello"} : { foo: string; } foo: "hello" >foo : string >"hello" : "hello" }; type T2 = keyof T1; >T2 : "foo" const e2: T2 = "foo"; >e2 : "foo" >"foo" : "foo" // Repro from #41133 interface Car { name: string; >name : string seats: number; >seats : number engine: Engine; >engine : Engine wheels: Wheel[]; >wheels : Wheel[] } interface Engine { manufacturer: string; >manufacturer : string horsepower: number; >horsepower : number } interface Wheel { type: "summer" | "winter"; >type : "summer" | "winter" radius: number; >radius : number } type Primitive = string | number | boolean; >Primitive : Primitive type OnlyPrimitives = { [K in keyof T as T[K] extends Primitive ? K : never]: T[K] }; >OnlyPrimitives : OnlyPrimitives let primitiveCar: OnlyPrimitives; // { name: string; seats: number; } >primitiveCar : OnlyPrimitives let keys: keyof OnlyPrimitives; // "name" | "seats" >keys : "name" | "seats" type KeysOfPrimitives = keyof OnlyPrimitives; >KeysOfPrimitives : keyof OnlyPrimitives let carKeys: KeysOfPrimitives; // "name" | "seats" >carKeys : "name" | "seats" // Repro from #41453 type Equal = (() => T extends A ? 1 : 2) extends (() => T extends B ? 1 : 2) ? true : false; >Equal : Equal >true : true >false : false type If = Cond extends true ? Then : Else; >If : If >true : true type GetKey = keyof { [TP in keyof S as Equal extends true ? TP : never]: any }; >GetKey : keyof { [TP in keyof S as Equal extends true ? TP : never]: any; } >true : true type GetKeyWithIf = keyof { [TP in keyof S as If, TP, never>]: any }; >GetKeyWithIf : keyof { [TP in keyof S as If, TP, never>]: any; } type GetObjWithIf = { [TP in keyof S as If, TP, never>]: any }; >GetObjWithIf : GetObjWithIf type Task = { >Task : Task isDone: boolean; >isDone : boolean }; type Schema = { >Schema : Schema root: { >root : { title: string; task: Task; } title: string; >title : string task: Task; >task : Task } Task: Task; >Task : Task }; type Res1 = GetKey; // "Task" >Res1 : "Task" type Res2 = GetKeyWithIf; // "Task" >Res2 : "Task" type Res3 = keyof GetObjWithIf; // "Task" >Res3 : "Task" // Repro from #44019 type KeysExtendedBy = keyof { [K in keyof T as U extends T[K] ? K : never] : T[K] }; >KeysExtendedBy : keyof { [K in keyof T as U extends T[K] ? K : never]: T[K]; } interface M { a: boolean; >a : boolean b: number; >b : number } function f(x: KeysExtendedBy) { >f : (x: KeysExtendedBy) => "b" >x : "b" return x; >x : "b" } f("a"); // Error, should allow only "b" >f("a") : "b" >f : (x: "b") => "b" >"a" : "a" type NameMap = { 'a': 'x', 'b': 'y', 'c': 'z' }; >NameMap : NameMap >'a' : "x" >'b' : "y" >'c' : "z" // Distributive, will be simplified type TS0 = keyof { [P in keyof T as keyof Record]: string }; >TS0 : keyof { [P in keyof T as P]: string; } type TS1 = keyof { [P in keyof T as Extract]: string }; >TS1 : keyof { [P in keyof T as Extract]: string; } type TS2 = keyof { [P in keyof T as P & ('a' | 'b' | 'c')]: string }; >TS2 : keyof { [P in keyof T as P & ("a" | "b" | "c")]: string; } type TS3 = keyof { [P in keyof T as Exclude]: string }; >TS3 : keyof { [P in keyof T as Exclude]: string; } type TS4 = keyof { [P in keyof T as NameMap[P & keyof NameMap]]: string }; >TS4 : keyof { [P in keyof T as NameMap[P & keyof NameMap]]: string; } type TS5 = keyof { [P in keyof T & keyof NameMap as NameMap[P]]: string }; >TS5 : NameMap[keyof T & "a"] | NameMap[keyof T & "b"] | NameMap[keyof T & "c"] type TS6 = keyof { [ K in keyof T as V & (K extends U ? K : never)]: string }; >TS6 : keyof { [K in keyof T as V & (K extends U ? K : never)]: string; } // Non-distributive, won't be simplified type TN0 = keyof { [P in keyof T as T[P] extends number ? P : never]: string }; >TN0 : keyof { [P in keyof T as T[P] extends number ? P : never]: string; } type TN1 = keyof { [P in keyof T as number extends T[P] ? P : never]: string }; >TN1 : keyof { [P in keyof T as number extends T[P] ? P : never]: string; } type TN2 = keyof { [P in keyof T as 'a' extends P ? 'x' : 'y']: string }; >TN2 : keyof { [P in keyof T as "a" extends P ? "x" : "y"]: string; } type TN3 = keyof { [P in keyof T as Exclude, 'b'>, 'a'>]: string }; >TN3 : keyof { [P in keyof T as Exclude, "b">, "a">]: string; } type TN4 = keyof { [K in keyof T as (K extends U ? T[K] : never) extends T[K] ? K : never]: string }; >TN4 : keyof { [K in keyof T as (K extends U ? T[K] : never) extends T[K] ? K : never]: string; } type TN5 = keyof { [K in keyof T as keyof { [P in K as T[P] extends U ? K : never]: true }]: string }; >TN5 : keyof { [K in keyof T as keyof { [P in K as T[P] extends U ? K : never]: true; }]: string; } >true : true