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}


 

 

藤沢瞭介(Ryosuke Hujisawa)
  • りょすけと申します。18歳からプログラミングをはじめ、今はフロントエンドでReactを書いたり、AIの勉強を頑張っています。off.tokyoでは、ハイテクやガジェット、それからプログラミングに関する情報まで、エンジニアに役立つ情報を日々発信しています!

未整理記事

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です