Menu

TypeScriptのユーティリティ型一覧(サンプル付き)

TypeScriptの組み込みユーティリティ型をすべて1か所にまとめました。Partial、Required、Readonly、Pick、Omit、Record、Exclude、Extract、NonNullable、Parameters、ReturnType、Awaited、文字列の型など、それぞれに1行の説明と実行できるサンプルを付けています。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

ユーティリティ型は、ある型を別の型に変える、TypeScriptに組み込まれたジェネリックな型です。すべてのフィールドを省略可能にした2つ目の User 型を書く代わりに Partial<User> と書き、3つのフィールドをコピーする代わりに Pick<User, "id" | "name"> と書きます。グローバルなので、インポートは要りません。

User が変われば、派生した4つの型もすべてそれに従います。TypeScriptの標準ライブラリ(lib.es5.d.ts)は22個のユーティリティ型を宣言しています。以下のセクションでは、扱う型の種類ごとにすべてを並べ、詳しいページがあるものにはリンクを付けています。

オブジェクト型: Partial、Required、Readonly、Pick、Omit、Record

ユーティリティ型働き例
Partial<T>すべてのプロパティを省略可能にする更新のペイロードに Partial<User>
Required<T>すべてのプロパティを必須にする(? を取り除く)デフォルト値を適用したあとの Required<Config>
Readonly<T>すべてのプロパティを readonly にするReadonly<State>
Pick<T, K>キー K だけを残すPick<User, "id" | "name">
Omit<T, K>キー K を取り除くOmit<User, "password">
Record<K, V>キーが K、値が V のオブジェクト型Record<"en" | "de", string>

Required<T> は Partial<T> の逆です。Partial のページで両方を扱っていて、このようなスプレッドが通してしまう明示的な undefined についても説明しています。

ユニオン型: Exclude、Extract、NonNullable

ユーティリティ型働き例
Exclude<U, M>M に代入できるユニオン型のメンバーを取り除くExclude<"a" | "b" | "c", "a"> は "b" | "c"
Extract<U, M>M に代入できるユニオン型のメンバーを残すExtract<string | number, number> は number
NonNullable<T>null と undefined を取り除くNonNullable<string | null> は string

この3つはオブジェクトではなくユニオン型に対して働きます。オブジェクト型とそのキーの一覧を受け取る Pick や Omit との大きな違いはそこです。

関数とクラスの型: Parameters、ReturnType など

ユーティリティ型働き例
ReturnType<F>関数型の戻り値の型ReturnType<typeof createStore>
Parameters<F>引数の型をタプルでParameters<typeof fetchPage>[0]
ConstructorParameters<C>クラスのコンストラクターの引数をタプルでConstructorParameters<typeof Point>
InstanceType<C>コンストラクターが作るインスタンスの型InstanceType<typeof Point>
ThisParameterType<F>関数の this パラメーターの型ThisParameterType<typeof greet>
OmitThisParameter<F>this パラメーターを除いた関数型greet.bind(obj) の型
ThisType<T>オブジェクトリテラルのメソッドの中の this の型を設定するビルダー型のAPIで noImplicitThis と一緒に使う
NoInfer<T>型パラメーターがこの位置から推論されるのを止めるfallback: NoInfer<C>

これらのユーティリティは型を受け取り、createOrder は値なので、typeof createOrder が必要です。クラスも同じで、typeof Point はコンストラクターの型ですが、型としての普通の Point はすでにインスタンスの型を意味します。

NoInfer は、ジェネリクスがどこから型を得るかを制御します:

NoInfer がなければ、TypeScriptは両方の引数から C を推論して "red" | "green" | "blue" に広げてしまうので、フォールバックの打ち間違いが受け入れられてしまいます。

文字列の型: Uppercase、Lowercase、Capitalize、Uncapitalize

ユーティリティ型働き例
Uppercase<S>文字列リテラル型を大文字にするUppercase<"get"> は "GET"
Lowercase<S>小文字にするLowercase<"GET"> は "get"
Capitalize<S>先頭の文字を大文字にするCapitalize<"name"> は "Name"
Uncapitalize<S>先頭の文字を小文字にするUncapitalize<"Name"> は "name"

この4つはTypeScriptで書かれているのではなくコンパイラーに組み込まれていて、イベントハンドラー名を作る `on${Capitalize<E>}` のように、テンプレートリテラル型 の中でいちばん役に立ちます。

Promise: Awaited

ユーティリティ型働き例
Awaited<T>await で得られる型。ネストした Promise も展開するAwaited<Promise<Promise<number>>> は number

Awaited<ReturnType<typeof fn>> は、async 関数の結果の型を別に宣言せずに名前を付ける標準的な方法です。

ユーティリティ型を組み合わせる

ユーティリティ型は入れ子にできます。覚えておく価値があるほどよく出てくる組み合わせがいくつかあります:

入れ子のユーティリティ型は内側から読みます。Readonly<Pick<Post, "id" | "title">> は、まず2つのプロパティを残し、それから読み取り専用にします。同じ部品で、一部のキーだけを省略可能にする PartialBy ヘルパーも作れます。Partial のページで書き出しています。

ユーティリティ型は実行時に何もしない

ユーティリティ型はすべて、コードのコンパイル時に消去されます。Omit<User, "password"> と型付けされた値でも、元のオブジェクトが password を持っていれば、実行時にはそれを持ったままです:

型が制限するのは、コードが読んでよいものだけです。データからフィールドを取り除くには最後の数行のように分割代入で取り除き、実行時に変更を止めるには Readonly ではなく Object.freeze を使いましょう。組み込みの型は1行のマップ型や条件型なので、同じ道具で自分の型も書けます。

よくある質問

TypeScriptのユーティリティ型とは何ですか?

TypeScriptに同梱されている、ほかの型を変換するジェネリックな型です。Partial<T> はすべてのプロパティを省略可能にし、Pick<T, K> は一部のプロパティを残し、ReturnType<F> は関数の戻り値の型を取得する、といったものです。標準ライブラリで宣言されているので、何もインポートせずに使えます。

ユーティリティ型はインポートする必要がありますか?

ありません。Partial、Omit、Record、ReturnType などは、TypeScriptの組み込みライブラリファイルのグローバルな型です。どこでも Partial<User> と書けて、インポートも npm パッケージも要りません。

TypeScriptにはどんなユーティリティ型が組み込まれていますか?

22個で、すべて lib.es5.d.ts で宣言されています: Partial、Required、Readonly、Pick、Omit、Record、Exclude、Extract、NonNullable、Parameters、ConstructorParameters、ReturnType、InstanceType、ThisParameterType、OmitThisParameter、ThisType、NoInfer、Awaited、Uppercase、Lowercase、Capitalize、Uncapitalize。

ユーティリティ型は実行時にオブジェクトを変えますか?

変えません。型を表すだけで、JavaScriptの出力からは消去されます。Omit<User, "password"> は password プロパティを削除せず、Readonly<T> は何も凍結しません。実際のオブジェクトを変えるには、分割代入の残余パターンや Object.freeze などのコードを書きます。

自分でユーティリティ型を書けますか?

書けます。組み込みのものも普通のTypeScriptで、ほとんどは lib.es5.d.ts にある1行のマップ型か条件型です。type Nullable<T> = { [K in keyof T]: T[K] | null } も同じ方法で書いた自作のユーティリティ型です。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める