TypeScript特有の組み込み型関数

TypeScriptにはPromiseやSymbolといったJavascript特有のグローバルオブジェクト以外に、型を扱う上で便利になるような組み込みのジェネリックな型関数※1が存在します。これらは非常に便利で様々なプロジェクトで使われているのですが、公式にリストもなく、説明も主にリリースノート等にしかないため、使い方等を交えて説明を書いていきたいと思います。

なお、各定義はMicrosoft/TypeScriptのsrc/lib/es5.d.tsにあります

※1 ... 型を受け取って新しい型を返す型。多分正しい呼び名ではない。

#Partial

type Partial<T>

型Tのすべてのプロパティを省略可能(つまり| undefined)にした新しい型を返すMapped Typeです。

interface Foo {
  bar: number
  baz: boolean
}

type PartialFoo = Partial<Foo>

// PartialFoo {
//   bar?: number
//   baz?: boolean
// }

ライブラリのオプションの型を書く時なんかに非常に役立ちます。

interface Options {
  host: string
  port: number
}

const defaultOptions: Options = {
  host: 'localhost',
  port: 3000
}

const main = (options: Partial<Options> = {}) => {
  const opts = { ...defaultOptions, ...options }

  // ...
}

// 使う側

main({
  port: 8080
})

#Required

type Required<T>

型Tの全てのプロパティを必須にした新しい型を返します。

interface Foo {
  bar?: number
  baz: boolean
}

type RequiredFoo = Required<Foo>

// RequiredFoo {
//   bar: number
//   baz: boolean
// }

#Readonly

type Readonly<T>

型Tの全てのプロパティにreadonly属性をつけた新しい型を返します。

interface Foo {
  bar: number
  baz: boolean
}

type ReadonlyFoo = Readonly<Foo>

// ReadonlyFoo {
//   readonly bar: number
//   readonly baz: boolean
// }

#Pick

type Pick<T, K extends keyof T>

型Tの中からKに当てはまるプロパティのみを抜き取った新しい型を返します。
なお、Kには型Tに存在するキーを指定する必要があります。

interface Foo {
  bar: number
  baz: boolean
  qux: string
}

type BarAndQux = Pick<Foo, 'bar' | 'qux'>

// BarAndQux {
//   bar: number
//   qux: string
// }

react-redux等のHoCを作成/使用する際に多用します。

#Omit

type Omit<T, K extends keyof any>

型Tの中から、キー名がKに当てはまるプロパティを除外した新しい型を返します。
なお、Pickとは異なりKにはTのキー名以外を指定することができます。

interface Foo {
  foo: string
  bar: number
  baz: boolean
}

type FooWithoutBar = Omit<Foo, 'bar'>

// FooWithoutBar {
//   foo: string
//   baz: boolean
// }

#Record

type Record<K extends keyof any, T>

型TなプロパティKを持つレコード型を作成します。

interface Foo {
  bar: number
  baz: boolean
}

type StringFoo = Record<keyof Foo, string>

// StringFoo {
//   bar: string
//   baz: string
// }

#Exclude

type Exclude<T, U>

型Tが型Uに代入可能であればnever、そうでなければ型Tを返すConditional Typeです。
主にUnion Typesから特定の型を取り除く際に使われます。

type A = Exclude<string, number> // string
type B = Exclude<string, any> // never
type C = Exclude<string | number | boolean, string | boolean> // number

#Extract

type Extract<T, U>

型Tが型Uに代入可能であれば型T、そうでなければneverを返すConditional Typeです。
Excludeの逆ですね。
主にUnion Typesから特定の型を抽出する際に使われます。

type A = Extract<string, number> // never
type B = Extract<string, any> // string
type C = Extract<string | number | boolean, string | boolean> // string | boolean

#NonNullable

type NonNullable<T>

型Tからnullundefinedを取り除いた型を返します。

type A = NonNullable<string | null> // string
type B = NonNullable<null> // never
type C = NonNullable<string> // string

#Parameters

  • 利用可能バージョン: TypeScript3.1~
  • リリースノート及びドキュメントに記載なし
type Parameters<T extends (...args: any[]) => any>

関数型Tの引数の型をタプルとして抽出します。

function foo(arg1: string, arg2: number): void {}
function bar(): void {}

type Foo = Parameters<typeof foo> // [string, number]
type Bar = Parameters<typeof bar> // []

ちょくちょく使える場面はあるので覚えておくと便利です。

#ConstructorParameters

  • 利用可能バージョン: TypeScript3.1~
  • リリースノート及びドキュメントに記載なし
type ConstructorParameters<T extends new (...args: any[]) => any>

型Tのコンストラクタの引数の型をタプルとして抽出します。
Parametersのコンストラクタ版です。

class Foo {
  constructor(arg1: string, arg2?: boolean) {}
}

type Bar = ConstructorParameters<typeof Foo> // [string, boolean] | [string]

#ReturnType

type ReturnType<T extends (...args: any[]) => any>

型Tの戻り値の型を返します。なお、Tには関数型のみ指定可能です。

const foo = () => 'foo'

type A = ReturnType<typeof foo> // string
type B = ReturnType<typeof window.setTimeout> // number
type C = ReturnType<() => void> // void

#InstanceType

type InstanceType<T extends new (...args:any[]) => any>

型Tのコンストラクタの返り値の型を返す型です。

class Foo {}

type A = InstanceType<typeof Foo> // Foo
type B = InstanceType<any> // any
type C = InstanceType<never> // any

使いどころが全くわからない...。

#ThisType

  • 利用可能バージョン: TypeScript2.3~
  • リリースノート及びドキュメントに記載なし
type ThisType<T>

thisの型をTとすることができる特殊な型です。型関数ではないですが便利なので一応記載します。

interface Foo { bar: number }
interface Baz { qux(): string }

const quux: ThisType<Foo> = {
  myMethod() {
    return this.bar
  }
}

const corge: Baz & ThisType<Foo> = {
  qux() {
    return this.bar.toString(16)
  }
}

Javascriptのライブラリを使う際にあると便利な型です。
詳細はQiitaに記事を上げてくれている人がいるので、それを参照してください。

TypeScript 2.3 RC 変更点@vvakame