課題

組み込みの Pick<T, K> を使用せず、T から K のプロパティを抽出する型を実装 してください。

例:

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = MyPick<Todo, "title" | "completed">;

const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
};

解答

この課題を解くためには、Lookup 型と Mapped 型を使う必要があります。

Lookup 型により、名前を用いてある型から別の型を抽出することができます。これはあ るオブジェクトからそのキーにより値を取得することと似ています。

Mapped 型により、ある型に含まれるプロパティを新しい型へと変換することができま す。

TypeScript のウェブサイト上で Lookup 型Mapped 型に 関する説明を読み、その挙動について理解しておきましょう。

以上で TypeScript には Lookup 型と Mapped 型が存在することがわかりました。では、 要求された型をどのように実装すればいいでしょうか?

ユニオン K からすべてのプロパティを抜き出し、各値について走査し、それらのみを キーとする新たな型を返す必要があります。これはまさしく Mapped 型の挙動と一致しま す。

値の型自体を変更する必要はありません。与えられた型から型情報を抜き出さなければな りませんが、それには Lookup 型を使うことができます:

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

ここで表現していることは、「K からすべてのプロパティを抜き出し、各値の名前を P とした上で、新しいオブジェクトのキーを P とし、またそれに対応する値の型 を、入力された型 T から得られるものとする」ということです。最初は理解すること が難しいかもしれません。もし何かわからないことがあれば、もう一度説明を読み直し、 順を追って理解していってください。

参考