
TypeScript の高度な型 ⑦ Utility Typesとは?
型を用いたコーディングを進めていくと、既存型の一部のみを使いたいということが良くあります。
前のブログでも書いた Conditional Types はまさにそういう場合に有効です。
TypeScriptプロジェクトでは、このような要望が頻繁に起こりますが、その都度、Conditional Types を定義するのは面倒くさいですよね。
幸いなことに、TypeScriptでは、凡庸的に利用できる「組み込み Utility Types」が標準で提供されています。
Utility Types では型のライブラリということが出来て、独自に定義を作ることもできます。
これらの型を利用することで、ユースケースに応じた型の付与を手早く行えます。
従来の組み込みUtility Ttpes
まずは、TypeScript 2.8以前から存在する「組み込みUtility Types」を紹介します。
いずれも、important を記述することなく利用できます。
ここで紹介する型は、下記に示した既存の型に対して、変換をかけるものとします。
interface User {
name: string
age: number | null
gender: 'male' | 'female' | 'other'
birthplace?: string
}
Readonly型
Object型のプロパティを、すべてreadonlyに変換し、新しい型を生成する型です。
type ReadonlyWrapUser = Readonly<User>
推論結果
type RequireWrapUser = {
readonly name: string
readonly age; number | null
readonly gender: "male" | "female" | "other"
readonly birthplace?: string | undefrined
}
Partial型
Object型のプロパティをすべてoptionalに変換し、新しい型を生成する型です。
type PartialWrapUser = Partial<User>
Require型
Object型のプロパティから、全てのOptionalを取り除き、新しい型を生成する型です。
type RequireWrapUser = Required<user>
Record型
第一Genericsに指定したプロパティ名称で、新しObject型を生成する型です。
type UserRecord = Record<'user, User'>
//型推論結果
type UserRecord = {
user: User
}
Pick型
第二Genericsに指定した名称のプロパティ型を、第一Genericsに指定した型から、新しいObject型を生成する型
type UserGender = Pick<User, 'gender'>
型推論結果
type UserGender = {
gender: 'male' | 'female' | 'other'
}
Omit型
第二Genericsに指定した名称のプロパティ型を、第一Genericsから取り除き、新しいObject型を生成する型です。
type WithoutBirthplace = Omit<User, 'birthplace'>
*ただし、この組み込みUtilit Types は TypeScript3.5で搭載される予定であり、それ以降では、独自に実装する必要があります。
//下記のように
type Omit<T, K extends typeof T> = Pick<T, Exclude<keyof T, K>>
//型推論結果
type WithoutBirthplace = {
name: string
age: number
gender: 'male' | 'female' | 'other'
}
新しい組み込みUtility Types
TypeScript2.8では、搭載されたConditional Typesを活用したUtility Types が追加されています。
「Exclude型」
Exclude<T, U>はT型からU型と互換性のある型を除き、新しい型を生成します。
type X = Exclude<"a" | "b" | "b"> // "a"
type Y = Exclude<"a" | ('( => void), Function> //"a"
「Extract型」
Extract<T, U> はT型からU型と互換性のある型を残し、新しい型を生成します。
type X = Extract<"a" | "b", "b"> //"b"
type Y = Extract<"a" | (() => void), function> //() => void
「NonNulable型」
NonNulable型はT型からnullおよびundefinedを除いた、新しい型を生成します。
type X = NonNullable<String | null | undefined> //string
「ReturnTypes」型」
ReturnTypes<T>は関数型であるT型の戻り型を抽出して、新しい型を生成します。
関数型以外を、Genericsに指定した場合は、コンパイルエラーになります。
type X = ReturnTypes<() => string> //string
type Y = Returntypes<string> //Error
「InstanceType型」
InstanceType型は、コンストラクター関数型のインスタンス型を取得します。
type C {
x = 0
y = 0
}
type X = InstanceType<typeoof>
const n = {} as X // {x: number: y: number}