【逆引き】Utility Types

# Utility Type とは？

[TypeScript 公式`](https://www.typescriptlang.org/docs/handbook/utility-types.html)

> TypeScript provides several utility types to facilitate common type transformations. These utilities are available globally.

型変換を容易にするための型です。
本稿では上記のページに記載されている Utility Type をすべて記載するわけではありませんのでご了承ください。

# オブジェクトのプロパティに関する Utility Type

## すべてのプロパティを任意のプロパティにした型を生成する

→ [`Partial<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype)

```typescript
type Foo = {
    hoge: string;
    fuga: number;
};
type PartialFoo = Partial<Foo>;
// {
//     hoge?: string | undefined;
//     fuga?: number | undefined;
// }
```

## すべてのプロパティを必須のプロパティにした型を生成する

→ [`Required<T>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#requiredtype)

```typescript
type Foo = {
    hoge?: string;
    fuga?: number;
};
type RequiredFoo = Required<Foo>;
// {
//     hoge: string;
//     fuga: number;
// }
```

## すべてのプロパティを読み取り専用にした型を生成する

→ [`Readonly<Type>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#readonlytype)

```typescript
type Foo = {
    hoge: string;
    fuga: number;
};
type ReadonlyFoo = Readonly<Foo>;
// {
//     readonly hoge: string;
//     readonly fuga: number;
// }
```

## 必要なプロパティのみを抜き出した型を生成する

→ [`Pick<Type, Keys>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#picktype-keys)

```typescript
type Foo = {
    hoge: string;
    fuga: number;
    piyo: boolean;
};
type PickFoo = Pick<Foo, "hoge">;
// {
//     hoge: string;
// }
type MultiPickFoo = Pick<Foo, "hoge" | "fuga">;
// {
//     hoge: string;
//     fuga: number;
// }
```

## 不要なプロパティを取り除いた型を生成する

→ [`Omit<Type, Keys>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys)

```typescript
type Foo = {
    hoge: string;
    fuga: number;
    piyo: boolean;
};
type OmitFoo = Omit<Foo, "hoge">;
// {
//     fuga: number;
//     piyo: boolean;
// }
type MultiOmitFoo = Omit<Foo, "hoge" | "fuga">;
// {
//     piyo: boolean;
// }
type AllOmitFoo = Omit<Foo, "hoge" | "fuga" | "piyo">;
// {}
// この状態だと上書き可能なため注意
```

# ユニオン型に関する Utilty Type

## 必要な要素のみを抜き出した方を生成する

→ [`Extract<Type, Union>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union)

```typescript
type Foo = "hoge" | "fuga" | "piyo";
type ExtractFoo = Extract<Foo, "hoge">;
// "hoge"
type MultiExtractFoo = Extract<Foo, "hoge" | "fuga">;
// "hoge" | "fuga"
```

## 不要な要素を取り除いた型を生成する

→ [`Exclude<Type, ExcludedUnion>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#excludetype-excludedunion)

```typescript
type Foo = "hoge" | "fuga" | "piyo";
type ExcludeFoo = Exclude<Foo, "hoge">;
// "fuga" | "piyo"
type MultiExcludeFoo = Exclude<Foo, "hoge" | "fuga">;
// "piyo"
```

## null と undefined を取り除いた型を生成する

→ [`NonNullable<Type>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#nonnullabletype)

```typescript
type Foo = "hoge" | "fuga" | "piyo" | null | undefined;
type NonNullableFoo = NonNullable<Foo>;
// "hoge" | "fuga" | "piyo"
```

# 引数に関する Utilty Type

## 引数の型をタプル型で取得する

→ [`Parameters<Type>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#parameterstype)

```typescript
function foo(hoge: string, fuga: number): void {}
type ParametersFoo = Parameters<typeof foo>;
// [hoge: string, fuga: number]
const parameters: ParametersFoo = ["str", 1];
foo(...parameters);
```

## コンストラクタの引数の型をタプル型で取得する

→ [`ConstructorParameters<Type>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#constructorparameterstype)

```typescript
class Foo {
    public constructor(hoge: string, fuga: number) {}
}
type ConstructorParametersFoo = ConstructorParameters<typeof Foo>;
// [hoge: string, fuga: number]
```

# 戻り値に関する Utility Type

## 戻り値の型を取得する

→ [`ReturnType<Type>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype)

```typescript
function foo(): string {
    return ``;
}
type ReturnTypeFoo = ReturnType<typeof foo>;
// string
```

# 辞書型に関する Utility Type

→ [`Record<Keys,Type>`](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeystype)

```typescript
type Union = "hoge" | "fuga" | "piyo";
type Foo = Record<string, number>;
// {
//     [x: string]: number;
// }
type Bar = Record<number, Union>;
// {
//     [x: number]: Union;
// }
type Baz = Record<Union, boolean>;
// {
//     hoge: boolean;
//     fuga: boolean;
//     piyo: boolean;
// }
```