mosya<TC> - 第2引数で指定したキーを除外した型を返す型を実装しようの解説
この記事はmosya<TC>の問題の一つであるMyOmit型の解説になります。
問題
組み込みの型ユーティリティOmit<T, K>を使用せず、TのプロパティからKを削除する型を実装します。
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = MyOmit<
Todo,
"description" | "title"
>;
const todo: TodoPreview = {
completed: false,
};
前提知識
この問題を解くにあたって型についての以下の知識を理解しておく必要があります。
Conditional Types
を理解するMapped Types
を理解する- インデックスアクセス型を理解する
- 便利な組み込み型
Exclude
を理解する
Conditional Typesを理解する
Conditional Typesは、条件によって型を変更することができる機能です。
例えば、以下のような型が考えられます。
type Foo<T> = T extends string
? string
: number;
この型は、T
がstring
型を継承している場合はstring
型を、そうでない場合はnumber
型を返します。
このように、extends
を使って条件を指定することで、型を変更することができます。
Mapped Typesを理解する
Mapped Types
はユニオン型を使って、新しいオブジェクトの型を生成する機能です。
例えば、以下のようなユニオン型があったとします。
type TodoKeys = "title" | "description";
このユニオン型を使って、以下のようなオブジェクトの型を生成することができます。
type Todo = {
[K in TodoKeys]: string;
};
// 以下のように展開される
type Todo = {
title: string;
description: string;
};
インデックスアクセス型を理解する
インデックスアクセス型
は、オブジェクトのプロパティにアクセスするための機能です。
例えば、以下のようなオブジェクトがあったとします。
interface Todo {
title: string;
description: string;
}
このオブジェクトのプロパティにアクセスするには、以下のようにします。
type Title = Todo["title"]; // string
このように、Todo["title"]
とすることで、Todo
のtitle
プロパティの型を取得することができます。
これをインデックスアクセス型と呼びます。
先ほど登場したMapped Types
と組み合わせることで、一つずつオブジェクトのプロパティにアクセスすることができます。
便利な組み込み型 Exclude を理解する
Exclude
は、ユニオン型から特定の型を除外することができる便利な組み込み型です。
例えば、以下のようなユニオン型があったとします。
type Foo = string | number | boolean;
このユニオン型からstring
型を除外するには、以下のようにします。
type Bar = Exclude<Foo, string>; // number | boolean
解答例
以上の知識を使って、以下のように解答することができます。
type MyOmit<T, K> = {
[P in Exclude<keyof T, K>]: T[P];
};
- まず、
Exclude<keyof T, K>
で、T
のプロパティのキーからK
を除外します。 - 除外されたキーを使って
Mapped Types
を使い、新しいオブジェクトの型を生成します。 T[P]
で、インデックスにアクセスして、T
のプロパティの型を取得します。
Authored by
Godai@steelydylan
Webサービスを作るのが好きなWebエンジニア。子供が産まれたことをきっかけに独立し法人化。サービス開発が大好き。
好きな言語はTypeScript。