# typescirpt hater learn typescript: 2-1, before infer (generic, condition type, mapped type, keyof, typeof ) ### generic ``` ts type Cat = { name: string; age: number }; type CatT<T> = { name: string; age: T }; let c: CatT<number>; let c2: CatT<string>; ``` ### condition type (typescript if-else statement) ```ts= type BooleanN<T> = T extends number ? true : false; let b1: BooleanN<number>; let b2: BooleanN<string>; type isTwo<T> = T extends 2 ? true : false; let i1: isTwo<2>; let i2: isTwo<100>; ``` ### [build-in utilty type](https://www.typescriptlang.org/docs/handbook/utility-types.html) (generic + condition type) ```ts // type Exclude<T, U> = T extends U ? never : T; interface Animal {} interface Dog extends Animal {} let e1: Exclude<string, number>; let e2: Exclude<Dog, Animal>; // Extract, NonNullable .... ``` ### keyof (取出物件型別的 key,並建立成一個新的 type) ```ts type Cat = { name: string, age: number, } type CatProp = keyof Cat; let cp:CatProp; type ArrProp = keyof []; type StringProp = keyof string; ``` ### Index signature / mapped type ```ts type Cat = { name: string; age: number; }; // type CatMap = { // a: Cat, // b: Cat, // } // Index signature type CatMap = { [x: string]: Cat }; let cm: CatMap = { a: { name: 'tom', age: 16 }, b: { name: 'john', age: 12 }, }; type CatMap2<T> = { [x: string]: T }; let cm2: CatMap2<Cat> = { a: { name: 'tom', age: 16 }, b: { name: 'john', age: 12 }, }; // mapped type // loops over all of the keys 'a', 'b' type CatMap3 = { [x in 'a' | 'b']: Cat }; let cm3: CatMap3 = { a: { name: 'tom', age: 16 }, b: { name: 'john', age: 12 }, }; type CatMap4<T extends string, U> = { [x in T]: U }; type cm4 = CatMap4<'a' | 'b', Cat>; let cm4Obj: cm4 = { a: { name: 'tom', age: 16 }, b: { name: 'john', age: 12 }, }; // keyof + mapped type ? type Person = { name: string }; type WhatIsThis = keyof { [x: string]: Person }; type WhatIsThis2 = keyof { [y: number]: Person }; let w: WhatIsThis; // so ... type DD2 = keyof { [x: string]: object }; type DD3 = keyof { [x: string]: boolean }; type DD4 = keyof { [y: string]: Cat }; type DD5 = keyof { [y: string]: object }; type DD6 = keyof { [y: string]: boolean }; ``` ### Pick (mapped type + keyof) ```ts type Cat = { name: string, age: number, weight: number, } // type Pick<T, K extends keyof T> = { // [P in K]: T[P]; // }; type NA = Pick<Cat, "name" | "age">; ``` ### typeof ``` ts const cat = { name: 'kuro' age: 10 } type Cat = typeof cat; let c:Cat; type CatN = typeof cat['name'] ``` ### keyof + typeof combine ```ts= const cat = { name: 'kuro', age: 10 } type CatProp = keyof typeof cat; type CatPropType = typeof cat[keyof typeof cat]; ```