🦁

【 TypeScript 】"as"と"&"を使って詳しい型情報を提供する

2023/10/13に公開

次のようなコールバック関数を作成したとします。

const getMyPet = () =>
  document.documentElement.getAttribute('myPet')
// const getMyPet: () => string | null

関数の戻り値はstring | nullとなっています。しかし引数でmyPetを指定しているので、戻ってくる値は何かしらの具体的な文字列の可能性があります。

事前に次の型を作成していたとします

type MyPet = 'tama' | 'pochi'

getMyPet()の戻り値の型にMyPetも含める方法について考えます。

まず、as を使って戻り値の型を指定してみましょう。

const getMyPet = () =>
  document.documentElement.getAttribute('myPet') as MyPet
// const getMyPet: () => MyPet

MyPet型を指定することができました。しかし null型が失われているので補いましょう。

const getMyPet = () =>
  document.documentElement.getAttribute('myPet') as MyPet | null
// const getMyPet: () => MyPet | null

ただこのままでは、後で型情報を参照したときMyPet型の具体的な中身である'tama' | 'pochi' が表示されません。そこでIntersection型:& を使ってTypescriptに詳細情報を表示させましょう。

const getMyPet2 = () =>
  document.documentElement.getAttribute('myPet') as (MyPet & {}) | null
// const getMyPet2: () => "tama" | "pochi" | null

(MyPet & {}) の箇所は (MyPet & string) としても同じ型が得られます。

Intersection型の詳細は公式ドキュメントを見てください。

このままでも十分な気もするのですが、'tama','pochi'以外の文字列も戻ってくる可能性も残しておきましょう。

const getMyPet3 = () =>
  document.documentElement.getAttribute('myPet') as (MyPet & {}) | null | (string & {})
// const getMyPet3: () => "tama" | "pochi" | (string & {}) | null

(string & {})を加えることで、"tama" | "pochi"以外の文字列だった場合の条件式を作成するヒントが得られます。

以上です。

今回の例は TS playground で確認できます。

Discussion