---
# System prepended metadata

title: 'typescirpt hater learn typescript: 2-1, before infer (generic, condition type, mapped type, keyof, typeof )'

---

# 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]; 

```