ダウンキャストやアップキャストとは

公開日: 2023/05/08 @Miz_dev

TypeScript

ダウンキャストやアップキャストとは

型を変える行為のこと。

何故、型を変える必要があるのか

まず、以下のコードのように最初に定義した color は String Literal Types となるが、theme 内の color は string となる。

export const color = "red";
// const color: "red"

const theme = {
  color: "red",
  // (property) color: string
};

theme.color = "blue";

何故、このような挙動になるのか

TypeScript が JavaScript の仕様に基づいて作られているからで、JavaScript では const で宣言したものは後から変更ができない。
しかし、オブジェクト内のプロパティに関しては const でオブジェクトを定義していたとしても、変更出来る仕様になっている。
そのため、オブジェクト内の color が仮に string ではなく”red”で推論されたとして、後から変更できてしまうと不都合が起こる。
そうならないように、最初から TypeScript ではオブジェクト内のプロパティに対しては Literal Types で宣言されることがないようになっている。

このように、TypeScript は JavaScript の互換性を重視しているため、型推論の結果がプログラマの意図しないものになることが多々ある。
今回の例で、オブジェクト内の”red”は必ず”red”なので、string ではなく String Literal Types として最初から推論されてほしい場合にプログラマで挙動を変えることができる。
それが「ダウンキャスト」と「アップキャスト」。

ダウンキャスト

型推論で導かれた型が抽象的すぎる場合に、プログラマー側でより型を詳しくすること。
抽象度の高い方をより詳しい型にしていくこと。

as を使ったダウンキャスト

as 〇〇とすることで、設定することができる。

const theme = {
  color: "red" as "red",
};

ただし、以下のようにそもそも互換性が無いものに関してはエラーとなるので注意。

const theme = {
  color: "red" as number,
};

const assertion

自分が定義した値を性とする書き方。
設定されている値をそのまま使用したい場合はas constとすることで同様の結果が得られる。

const theme = {
  color: "red" as const,
};

オブジェクトに対して as const

オブジェクトの各プロパティにas constを付与したい場合は、以下のように最後にas constを記述することで、各プロパティにas constを付与した場合と同じ挙動となる。

const theme = {
  color: "red",
  backgroundColor: "blue",
} as const;

ちなみに、readonly も付与され読み取り専用(書き換えることが出来ない)となる。

const assertion を実践で使う例

何かしらの定数ファイルを作成するときによく使われる。
後で書き換えられると困るものに関しては、予め const assertion を用いて読み取り専用としておくと良い。

export const PATH = {
  INDEX: "/",
  LOGIN: "/login",
  REGISTER: "/register",
  PROFILE: "/profile",
} as const;

アップキャスト

型の抽象度を上げること。
ただし、TypeScript 開発においてはバグを生みやすくなるため、基本的にはアップキャストはするべきではない。

アップキャストを使用する場面

外部パッケージ等で型の定義が分からない場合など、型を自分の力だけでは解決出来ないとき。
as any」を用いて、型の抽象度を上げる。