この記事ではTypeScriptのユーティリティ型を徹底的にまとめます。
この記事を読めば、業務でユーティリティ型を使いこなせる状態になることができるでしょう。
この記事がTypeScriptを使いこなすための一助となれば幸いです。
TypeScriptのユーティリティ型とは?
そもそもTypeScriptのユーティリティ型(Utility Types)とは何なのでしょうか?
TypeScriptのユーティリティ型とは、一言でいうと、「型を加工するためのメソッド」のようなものです。
ユーティリティ型を利用することで、TypeScriptの型を柔軟に変換することができます。
TypeScriptのユーティリティ型徹底まとめ
次に、実際にTypeScriptのユーティリティ型をまとめていきます。
Required<T>
オブジェクト型のオプションプロパティを必須プロパティに変換するユーティリティ型です。
以下のようなuser型があるとします。
type user = { id: number, name?: string, age?: number }
これを、以下のようにRequiredに通します。
type RequiredUser = Required<user>
すると、RequiredUserは以下の型になります。
type RequiredUser = { id: number; name: string; age: number; }
Readonly<T>
オブジェクト型の全てのプロパティをreadonly(プロパティの値の書き換えができない状態)にすることができるユーティリティ型です。
以下のようなuser型があるとします。
type user = { id: number, name?: string, age?: number }
これを、以下のようにReadonlyに通します。
type ReadonlyUser = Readonly<user>
すると、ReadonlyUserは以下の型になります。
type ReadonlyUser = { readonly id: number; readonly name?: string; readonly age?: number; }
Partial<T>
オブジェクト型の全てのプロパティをオプションプロパティに変換するユーティリティ型です。
以下のようなuser型があるとします。
type user = { id: number, name: string, age: number }
これを、以下のようにPartialに通します。
type PartialUser = Partial<user>
すると、PartialUserは以下の型になります。
type PartialUser = { id?: number; name?: string; age?: number; }
Record<Keys, T>
プロパティのキーがKeys、プロパティの値がTであるオブジェクト型を作るユーティリティ型です。
例えばRecordを使って以下のようなuser型を定義します。
type user = Record<"firstName" | "middleName" | "lastName", string>
これは以下の型とイコールになります。
type user = { firstName: string; middleName: string; lastName: string; }
Pick<T, Keys>
指定したプロパティを基に新たなオブジェクト型を生成するユーティリティ型です。
以下のようなuser型があるとします。
type user = { id: number, name: string, age: number }
これを、以下のようにPickに通します。
type PickedUser = Pick<user, "id" | "name">
すると、PickedUserは以下の型になります。
type PickedUser = { id: number; name: string; }
Omit<T, Keys>
Pickとは逆で、指定したプロパティを取り除いたオブジェクト型を生成するユーティリティ型です。
以下のようなuser型があるとします。
type user = { id: number, name: string, age: number }
これを、以下のようにOmitに通します。
type OmittedUser = Omit<user, "id" | "name">
すると、OmittedUserは以下の型になります。
type OmittedUser = { age: number; }
Exclude<T, U>
ユニオン型から指定した型を取り除くユーティリティ型です。
以下のようなuser型があるとします。
type user = "taro" | "hanako" | "jiro"
これを、以下のようにExcludeに通します。
type excludedUser = Exclude<user, "jiro">
すると、excludedUserは以下の型になります。
type excludedUser = "taro" | "hanako"
Extract<T, U>
Excludeの逆で、ユニオン型TからUで指定した型だけを抜き出した型を生成するユーティリティ型です。
例えば以下のようなuser型があるとします。
type user = "taro" | "hanako" | "jiro";
これを、以下のようにExtractに通します。
type ExtractedUser = Extract<user, "taro">;
すると、ExtractedUserは以下の型になります。
type ExtractedUser = "taro"
NonNullable<T>
Tからnullとundefinedを取り除いた型を生成するユーティリティ型です。
以下のようなuser型があるとします。
type user = | { id: number; name: string; } | null | undefined;
これを、以下のようにNonNullableに通します。
type NonNullableUser = NonNullable<user>;
すると、NonNullableUserは以下の型になります。
type NonNullableUser = { id: number; name: string; }
Parameters<T>
関数型Tの引数の型をタプル型(固定長で異なる型の要素を持つ配列を表すための型)として抽出した型を生成します。
以下のような関数があるとします。
const func = (text: string, num: number) => { return `${text}:${num}`; };
これを、以下のようにParametersに通します。
type TypeFunc = Parameters<typeof func>;
すると、TypeFuncは以下の型になります。
[text: string, num: number]
ConstructorParameters<T>
T型のコンストラクタの引数の型をタプル型(固定長で異なる型の要素を持つ配列を表すための型)として抽出した型を生成します。
以下のようなclassがあるとします。
class User { name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } }
これを、以下のようにConstructorParametersに通します。
type UserType = ConstructorParameters<typeof User>;
すると、UserTypeは以下の型になります。
type UserType = [name: string, age: number]
ReturnType<T>
関数型Tの戻り値の型を生成します。
以下のような関数があるとします。
const func = (): { user: { name: string; age: number } } => { return { user: { name: "taro", age: 23 } }; };
これを、以下のようにReturnTypeに通します。
type TypeReturn = ReturnType<typeof func>;
すると、TypeReturnは以下の型になります。
type TypeReturn = ReturnType<typeof func>;
ThisParameterType<T>
関数型Tのthis引数の型を抽出した型を生成します。
以下のような関数があるとします。
function func(this: Number) { return this.toString(); }
これを、以下のようにThisParameterTypeに通します。
type TypeFunc = ThisParameterType<typeof func>;
すると、TypeFuncは以下の型になります。
type TypeFunc = Number
OmitThisParameter<T>
関数型Tのthis引数の型を取り除いた型を生成します。
以下のような関数があるとします。
function func(this: Number) { return this.toString(); }
これを、以下のようにOmitThisParameterに通します。
type TypeFunc = OmitThisParameter<typeof func>;
すると、TypeFuncは以下の型になります。
type TypeFunc = () => string
Awaited<Type>
“Await”という名前からも分かると思いますが、Promise型をunwrapする型です。
以下のような型があるとします。
type PromiseString = Promise<string>;
これを、以下のようにAwaitedに通します。
type AwaitedType = Awaited<PromiseString>;
すると、AwaitedTypeは以下の型になります。
type AwaitedType = string
Uppercase<StringType>
文字列型をUppercaseにします。
以下のようにUppercaseを通します。
type UppercaseString = Uppercase<"hoge">;
すると、UppercaseStringは以下の型になります。
type UppercaseString = "HOGE"
Lowercase<StringType>
文字列型をLowercaseにします。
以下のようにLowercaseを通します。
type LowercaseString = Lowercase<"HOGE">;
すると、LowercaseStringは以下の型になります。
type LowercaseString = "hoge"
実務ではどれを使うことが多い?
今回は多くのユーティリティ型を紹介しましたが、実務で頻繁に使うものは限られています。
あくまで私が参加しているプロジェクト基準ではありますが、以下のユーティリティ型は特に使うので、しっかりと理解しておいた方が良いでしょう。
- Required
- Partial
- Pick
- Omit
- Exclude
- NonNullable
ユーティリティ型を組み合わせて自作の型を作る
ユーティリティ型を組み合わせることで、自作の型を作ることも可能です。
例えば、以下の記事の場合、OmitやNotNullable等のユーティリティ型を組み合わせて、PartialNotNullableという型を生成しました。
おわりに
最後まで読んでいただきありがとうございました。
この記事がTypeScriptのユーティリティ型への理解を深める上で少しでも参考になっていれば幸いです。