[TypeScript]Partialについて、実際に実装して理解する。

TypeScriptの既存の型から全てのプロパティをOptionalにして新たな型にするPartialというものがある。
今回はこれを自力で実装しながらPartialについて理解することを目的とする。

Partialとは

Partialとは以下の書式を持つ組み込み型で、ジェネリクスに指定したプロパティの全てをOptionalにしてくれるものです。
なお、PartialではネストされたプロパティについてはOptionalには出来ません。

// Partial<T> Tに指定された型のキーを全てOptionalにする。

type User = {
  id: number;
  name: String;
};

type PartialUser = Partial<User>

// type PartialUser = {
//   id?: number;
//   name?: String;
// }

今回はこれを実装して理解していきます。
すなわち以下のMyParcialを実装していきます。

type PartialUser = MyPartial<User>

// type PartialUser = {
//   id?: number;
//   name?: String;
// }

MyPartialの実装方針

MyPartialを実装するにあたって、以下の方針で段階を踏んで実装していきます。

  1. MyPartial<T>に指定されたプロパティのキーを羅列する
  2. それぞれのキーに対して、Tの型を設定する。
  3. 羅列されたプロパティを全てOptionalにする

では順に見ていきましょう

MyPartial<T>に指定されたキーを羅列する

プロパティのキーを羅列するにはkeyofを使用します。
そのため、Tのキーを羅列するには以下のようにすることで可能です。

type keys = keyof T

// 例
type UserKeys = keyof User
// type Userkeys = "id" | "name"

ただ、これだけではキーを羅列しただけで、キーに対する方を設定することが出来ません。
次にこの型を設定していきます。

それぞれのプロパティのキーに対して、Tの型を設定する。

TypeScriptにはMapped Typesと呼ばれる、元の型に基づいて新しい型を作成可能な仕組みがあります。
これを用いて、Tの型を設定していきます。
以下はMapped Typesを用いて、Userのプロパティのキー全てに対してStringを設定した例です。

type MyPartial<T> = {
  [K in keyof T]: String;
};

type my = MyPartial<User>
// type my = {
//     id: String;
//     name: String;
// }

このStringの部分を元のプロパティの型に設定してあげれば良さそうですね。
これは以下のようにすることで可能です。

type MyPartial<T> = {
  [K in keyof T]: T[K];
};

type my = MyPartial<User>
// type my = {
//     id: number;
//     name: String;
// }

T[K]とすることで、上記の例だと、id: User["id"], name: User["name"]を設定しているのと同等となります。
これで、だいたい完成ですね。

後は、それぞれのプロパティをOptionalにするだけです。

羅列されたプロパティを全てOptionalにする

これは簡単ですね。
それぞれのプロパティをOptionalにするだけなので、以下で実現可能です。

type MyPartial<T> = {
  [K in keyof T]?: T[K];
};

これで完成です。

まとめ

今回はPartialの実装を順を追って実装していきました。
理解出来ましたでしょうか?
いきなり最終形を見せられても順を追っていくことで理解出来ると思います。
ちなみにRequiredと呼ばれる組み込み型もありますので、この記事を参考に実装してみてください。

コメント