TypeScript の lookup 型をマスターしよう

TwitterFacebookHatena

TL;DR

今回は TypeScript の lookup 型について一緒に学びましょう。一言でいうと、lookup 型は既存の型から特定のプロパティの型を「引き出す」ための型です。

以下が今回の開発環境です。

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

lookup 型とは?

lookup 型は、TypeScript でよく使われる型の一つです。TypeScript では、型を「見つける」ための特殊な構文があり、その一つが lookup 型です。これは既存の型から特定のプロパティの型を「引き出す」ことができます。

たとえば、次のような型があったとします。

type User = {
  name: string
  age: number
  address: {
    street: string
    city: string
  }
}

このUser型から、addressプロパティの型を取り出したい場合、lookup 型を使って以下のように書けます。

type Address = User['address']

これで、Address型はUser型のaddressプロパティの型となります。つまり、次のようになります。

type Address = {
  street: string
  city: string
}

ユニオン型のキーの抽出

ユニオン型からキーを抽出するときには、lookup 型を用いることができます。

type PetTypes = 'dog' | 'cat' | 'fish'
type PetSpeak = {
  dog: 'bark'
  cat: 'meow'
  fish: 'bubble'
}

type DogSpeak = PetSpeak['dog'] // 'bark'

上記の例では、PetSpeak型から'dog'のキーを抽出して、その結果の型('bark')をDogSpeak型としています。

動的なキーの抽出

あるキーがどの値を持つかを動的に決定する場合も、lookup 型が役立ちます。

function getSpeak(pet: PetTypes): PetSpeak[PetTypes] {
  const petSpeak: PetSpeak = {
    dog: 'bark',
    cat: 'meow',
    fish: 'bubble',
  }

  return petSpeak[pet]
}

上記の関数getSpeakでは、渡されたペットの種類に基づいて、対応する「話し言葉」を返します。ここでは、lookup 型を用いて動的に返す値の型を決定しています。

以上のように、lookup 型はそのキーを用いて型情報を抽出することを可能にするため、TypeScript の型システムにおいてとても便利なツールとなります。

lookup 型の応用

では、もっと実践的な例を見てみましょう。lookup 型を使うことで、より具体的な型を抽出できます。

type Response = {
  users: {
    id: number
    name: string
    email: string
  }[]
  products: {
    id: number
    name: string
    price: number
  }[]
}

type Users = Response['users']
type User = Users[0]
type Products = Response['products']
type Product = Products[0]

これでUser型やProduct型を個々に使用できます。

const user: User = { id: 1, name: 'Alice', email: 'alice@example.com' }
const product: Product = { id: 1, name: 'Apple', price: 100 }

lookup 型を理解すると、より詳細な型情報を効果的に管理できます。TypeScript を使用する際には、このような型の取り扱いが非常に役立ちます。

lookup 型の制限

しかし、lookup 型には一部制限があります。それは、「数値リテラル型」や「文字列リテラル型」に対する lookup が可能である一方、変数に対する lookup は型安全を保証できないため、TypeScript では許可されていません。

例えば以下のようなコードを考えてみてください。

type Colors = {
  red: '#FF0000'
  green: '#00FF00'
  blue: '#0000FF'
}

const color = 'red'
const hex: Colors[color] // Type error

ここではcolorという変数を使って lookup を試みていますが、これは TypeScript の型チェックに違反するためエラーとなります。なぜなら、colorが実行時にどの値を持つかはコンパイル時には分からないからです。したがって、型安全を保証するために、TypeScript ではこのような操作は許可されていません。

TypeScript の lookup 型をマスターしよう