keyof
The keyof
operator takes an object type and produces a string or numeric literal union of its keys.
typeof
refer to the type of a variable or property
结合 ReturnType
获取实际函数的返回值类型
1 2 3 4 5 6 7 function f (a: string , b:string ) { return a + b; } type a11 = ReturnType <f> type a11 = ReturnType <typeof f>
Indexed Access Types(索引访问类型)
获取值 类型
获取数组内的值类型
结合 keyof 获取所有值类型
1 2 3 type Age = Person ["age" ];type AgeAndName = Person ["age" | "name" ];type All1 = Person [keyof Person ];
也可以接收对象的keyof,获取对象值的类型
1 2 3 4 5 6 type a = { a : stirng; b : string ; c : number ; } type b = a[keyof a]
类型只能接收类型
Indexed Union Types(索引联合类型) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 type test3 = { key : 'cow' value : 'yellow' sun : false } type testExpect3 = { key : 'cow' value : 'yellow' sun : false isMotherRussia : false | undefined } type cases = [ Expect <Equal <AppendToObject <test3, 'isMotherRussia' , false | undefined >, testExpect3>>, ] type AppendToObject <T, U extends string , V> = { [K in keyof T | U]: K extends U ? V : K extends keyof T ? T[K] : never ; }
Conditional Type(条件类型) 类型编程 依赖 extends
作为条件,返回 TrueType
or FalseType
SomeType extends OtherType ? TrueType : FalseType
When the type on the left of the extends
is assignable to the one on the right, then you’ll get the type in the first branch (the “true ” branch); otherwise you’ll get the type in the latter branch (the “false ” branch).
eg:递归平铺 1 2 3 4 5 6 7 8 9 type Flatten <T> = T extends any [] ? Flatten <T[number ]> : T;type Complex = [ [ [string ] ] ] type res1 = Flatten <number >; type res2 = Flatten <Complex >;
Inferring Within Conditional Types eg:递归平铺使用infer
1 2 3 4 5 6 7 8 9 type Flatten <Type > = Type extends Array <infer Item > ? Flatten <Item > : Type ;type Complex = [ [ [string ] ] ] type res1 = Flatten <number >; type res2 = Flatten <Complex >;
通过关键字 infer 声明了一个新的类型变量,infer 可以作为中间值进行后续运算也可以作为结果。
可以作为函数签名返回值类型;例如 ReturnType utilsType
可以作为数组的元素类型;例如
对于重载的函数签名是只能推断最后一个函数签名。 1 2 3 4 5 declare function stringOrNum (x: string ): number ;declare function stringOrNum (x: number ): string ;declare function stringOrNum (x: string | boolean ): string | boolean ;type T1_1 = ReturnType <typeof stringOrNum>;
Distributive(分配律) 如果是在条件类型中使用联合类型 ,那么则符合分配律的结果。
即联合类型的结果仍然是联合类型
1 2 3 4 5 type ToArray <T> = T extends any ? T[] : never ;type _3 = ToArray <string | number >;
1 2 3 4 5 ToArray<string | number> ==> ToArray<string> | ToArray<number>; ==> string[] | number[]
never是特殊的联合类型 1 2 3 4 type ExA <T> = T extends string ? true : false ;type res = ExA <never >;
eg
how to fix the question 1 2 3 4 type ToArrayNonDist <Type > = [Type ] extends [any ] ? Type [] : never ; type StrArrOrNumArr = ToArrayNonDist <string | number >;
Mapped Types 类似于index signature ,但可以做泛型化处理。
Mapping Modifiers
通过 “**+” or “ -**” 添加或移除修饰符(readonly、 ?)
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 type K<T> = { [k in keyof T]-?: boolean ; } type FeatureFlags = { name?: string ; darkMode : () => void ; newUserProfile : () => void ; }; type FeatureK = K<FeatureFlags >;type K<T> = { [k in keyof T]+?: boolean ; }
Key Remapping via as
In TypeScript 4.1 and onwards, you can re-map keys in mapped types with an as
clause in a mapped type
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 type removeOptional<T> = { [K in keyof T]-?: T[K]; } type ConvertKeys <T> = { [K in keyof T as `get${Capitalize<K & string >} ` ]: T[K]; } type ConvertKeys <T> = { [K in keyof T as `get${Capitalize<K & string >} ` ]-?: T[K]; } type _ = ConvertKeys <removeOptional<Person >>;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 type SquareEvent = { kind : "square" , x : number , y : number };type CircleEvent = { kind : "circle" , radius : number };type EventConfig <T extends {kind : string }> = { [E in T as E["kind" ]]: (k: E ) => void ; } type Config = EventConfig <SquareEvent | CircleEvent >
a mapped type using a conditional type Template Literal Types 1 2 3 4 5 type World = 'world' ;type Greeting = 'hello' + World ; type Greeting = `hello ${World} `
use union type 1 2 3 4 5 6 7 8 9 type EmailLocaleIDs = "welcome_email" | "email_heading" ;type EmailLocaleID = `${EmailLocaleIDs} _id` ;type FooterLocaleIDs = "footer_title" | "footer_sendoff" ;type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs} _id` ;
符合分配律知识