【TypeScript】Utility Types

## Partial`<T>`
`T`の全てのプロパティをOptionalにする。
```ts
type Profile = {
  name: string
  age: number
  zipCode: number
}

type PartialType = Partial<Profile>
// type PartialType = {
//   name?: string | undefined;
//   age?: number | undefined;
//   zipCode?: number | undefined;
// }
```

## Required`<T>`

`T`の全てのプロパティを全て必須にする。

```ts
type Profile = {
  name: string
  age?: number
  zipCode?: number
}

type RequiredType = Required<Profile>
// type RequiredType = {
//   name: string;
//   age: number;
//   zipCode: number;
// }
```

## Readonly`<T>`
`T`のプロパティを全て`readonly`にする。

```ts
type Profile = {
  name: string
  age: number
}

type PersonalDataType = Readonly<Profile>

const friend: PersonalDataType = {
  name: "田中",
  age: 19
}

// friend.age++
// error TS2540: Cannot assign to 'age' because it is a read-only property.

type Yomitorisenyo<T> = {
  readonly [P in keyof T]: T[P];
};
type YomitorisenyoProfile = Yomitorisenyo<Profile>
// type YomitorisenyoProfile = {
//   readonly name: string;
//   readonly age: number;
// }

```

## Record`<K, T>`
`Record<K, T>`は`K`がプロパティの`T`型を持つレコード型を構築する。

```ts
type Prefectures = "Tokyo" | "Chiba" | "Kyoto"

type DemographicsInfo = {
  kanji_name: string
  population: number
}

const Demographics : Record<Prefectures, DemographicsInfo> = {
  Tokyo: { kanji_name: "東京", population: 13515 },
  Chiba: { kanji_name: "千葉", population: 6223 },
  Kyoto: { kanji_name: "京都", population: 2610 },
}
```


## Exclude`<T,U>`
`T`のプロパティで`U`と互換性のあるプロパティを除いた型を構築する。
```ts
// Exclude<ユニオン型, 除外する型>
type DebugType = () => void
type SomeTypes = string | number | DebugType
type FunctionType = Exclude<SomeTypes, string | number>
type NonFunctionType = Exclude<SomeTypes, DebugType>
// 関数を除外する場合
type TypeExcludingFunction = Exclude<SomeTypes, Function>

// type Exclude<T, U> = T extends U ? never : T;
// type MyExclude = 
// ( string extends string | number ? never : string )  // never
// | ( number extends string | number ? never : number )  // never
// | ( DebugType extends string | number ? never : DebugType )  // DebugType
// type MyFunctionType = MyExclude

```

## Extract`<T,U>`
`T`の中から`U`と互換性のあるプロパティのみ残した型を構築する。

```ts
// Extract<ユニオン型, 抽出する型>
type FunctionTypeByExtract = Extract<SomeTypes, DebugType>
type NonFunctionTypeByExtract = Extract<SomeTypes, string | number>
type TypeExcludingFunctionByExtract = Extract<SomeTypes, Function>
```

# NonNullable`<T>`
`T`から`null`と`undefined`を除いた型を構築する。
```ts
// nullとundefinedを除外する
type NullableTypes = string | number | null | undefined
type NonNullableTypes = NonNullable<NullableTypes>
```

## Pick`<T,K>`
`T`の中から`K`で選択したプロパティのみを含んだ型を構築する。

```ts
type DetailedProfile = {
  name: string
  height: number
  weight: number
}

type SimpleProfile = Pick<DetailedProfile, "name" | "weight">
//  type SimpleProfile = {
//      name: string;
//      weight: number;
//  }

type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};
```

## Omit`<T,K>`
`T`の中から`K`で選択したのプロパティを除いた型を構築する。

```ts
type DetailedProfile = {
  name: string
  height: number
  weight: number
}

type SmallProfile = Omit<DetailedProfile, "height">
// type SmallProfile = {
//   name: string;
//   weight: number;
// }

// type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
// K = height
// keyof T = "name" | "height" | "weight"
// Exclude<keyof T, K> = Exclude<"name" | "height" | "weight", "height"> = "name", "weight"
// type MyOmit = Pick<DetailedProfile, 'name' | 'weight'>;
// type MySmallProfile = MyOmit
```