TypeScript のインターセクション型の使い方

TwitterFacebookHatena

TL;DR

このページでは、TypeScript のインターセクション型の実装方法について解説しますね。一言でいうと、インターセクション型とは複数の型を一つに結合する方法です。

開発環境 バージョン
Next.js 13.4.4
TypeScript 5.0.4
Emotion 11.11.0
React 18.2.0

インターセクション型とは?

TypeScript では、一つの値が複数の型を持つことができます。これをインターセクション型といいます。たとえば、ある人物の情報を表す型を作りたい場合、名前と年齢、趣味など、それぞれを個別の型として作ることができます。しかし、それらを組み合わせて一つの「人物」型を作りたい場合、インターセクション型を使うとスムーズです。

type Name = {
  name: string
}

type Age = {
  age: number
}

type Person = Name & Age

const person: Person = {
  name: 'John',
  age: 20,
}

このようにして、Name型とAge型を一つにまとめた新たなPerson型を作ることができました。このPerson型はName型とAge型のインターセクション(交差)型です。これがインターセクション型の基本的な考え方です。

型の結合

次に、少し複雑なソースコードを見てみましょう。今度は、それぞれの型が持つプロパティが多い場合に、どのようにインターセクション型を使うのかについて説明します。

type Work = {
  company: string
  position: string
}

type Person = Name & Age & Work

const person: Person = {
  name: 'John',
  age: 20,
  company: 'Tech Corp',
  position: 'Engineer',
}

ここでは、新たにWork型を定義し、それをPerson型に追加しました。このように、既存の型に新たな型を追加することで、より詳細な型を作ることができます。インターセクション型は、既存の型を結合して新たな型を作る際に非常に便利な機能です。

さらに、インターセクション型を使うことで、既存の型を改変することなく新たな型を作ることができるため、型の再利用が可能となります。これにより、コードの冗長性を減らし、読みやすさとメンテナンス性を向上させることができます。

複数のオブジェクト型

先ほどは二つのオブジェクト型のインターセクション型を使って見ましたが、もちろん、それ以上の複数のオブジェクト型のインターセクションを使うこともできます。さらに深く理解するために、三つのオブジェクト型を組み合わせた例を見てみましょう。

type Engine = {
  engineType: string
}

type Body = {
  color: string
  numberOfDoors: number
}

type Car = Engine &
  Body & {
    brand: string
  }

const myCar: Car = {
  engineType: 'V8',
  color: 'Black',
  numberOfDoors: 4,
  brand: 'Mercedes',
}

console.log(myCar)

この例では、Engine と Body という二つの型を作り、そしてその二つの型と別のプロパティを持つオブジェクトを合体させて新たな型 Car を作っています。その結果として Car 型は、engineType、color、numberOfDoors、brand の四つのプロパティを持つことになります。

こうしてみると、インターセクション型を使うことで、異なる型を効率良く組み合わせて新たな型を作ることができます。これはコードの再利用性を高め、コードの量を減らすことに寄与します。

関数型のインターセクション

type FunctionType1 = {
  (x: number): number
}

type FunctionType2 = {
  (y: string): string
}

type CombinedFunctionType = FunctionType1 & FunctionType2

const combinedFunction: CombinedFunctionType = (x: number | string) => {
  if (typeof x === 'number') {
    return x * 2
  } else {
    return x + '!'
  }
}

console.log(combinedFunction(2)) // 4
console.log(combinedFunction('Hello')) // "Hello!"

上記のコードでは、FunctionType1 と FunctionType2 という二つの関数型を作っています。それぞれの関数型はそれぞれ異なる型の引数を受け取り、同じ型の値を返す関数を表しています。CombinedFunctionType はこれら二つの関数型を組み合わせた新たな関数型です。

このようにインターセクション型を使うことで、型の組み合わせにより柔軟性と再利用性を持つコードを作ることができます。インターセクション型は TypeScript の強力な機能の一つであり、うまく使えば大規模なプロジェクトでも型の管理を効率的に行うことができます。

TypeScript のインターセクション型の使い方