TypeScript で型が強い定数を切る

2020-07-29

いっつも忘れるので、備忘録がてら。

const assertions

const hoge = ["fuga", "piyo"] as const;

キャストっぽい書き方ですよね。

ちなみに .tsx ファイル以外だと以下の書き方もできます。

const hoge = <const>["fuga", "piyo"];

この書き方を .tsx ファイルで許容しちゃうと html タグと混同しそうですよね、納得。

具体的なイメージは以下の通りです。

// const hoge: {
//     fuga: string;
//     piyo: string;
// }
const hoge = {
  fuga: "fugafuga",
  piyo: "piyopiyo",
};

// const hoge: {
//     readonly fuga: "fugafuga";
//     readonly piyo: "piyopiyo";
// }
const hoge = {
  fuga: "fugafuga",
  piyo: "piyopiyo",
} as const;

一目瞭然ですね、型がガッチガチになります。

Readonly の型引数にいちいち型を割り当るほどでもないときに便利です。

あと、たまに勘違いしている人がいますが、下記の書き方は全く意味合いが異なります。

type Hoge = Readonly<{
  fuga: "fugafuga";
  piyo: "piyopiyo";
}>;

const hoge: Hoge = {
  fuga: "fugafuga",
  piyo: "piyopiyo",
};
const hoge = {
  fuga: "fugafuga",
  piyo: "piyopiyo",
} as const;

type Hoge: typeof hoge;

上の書き方は、定数 hoge に型 Hoge を割り当てている状態です。

下の書き方は、定数 hoge を切って、その型が Hoge となっています。

で、基本的には上の書き方を行うケースのほうが多いのかなーと個人的には。

下の書き方は値から型を生成しちゃっているので、好ましくないケースがほとんどなのかなーと。

as const を使い、かつ定数に型を付与する場合は、以下の書き方が正しいのかなと。

type Hoge = Readonly<{
  fuga: "fugafuga";
  piyo: "piyopiyo";
}>;

const hoge: Hoge = {
  fuga: "fugafuga",
  piyo: "piyopiyo",
} as const;

まぁ、こんな書き方をするケースはないと思っていますが、どうなんでしょう。

TypeScript で型が強い定数を切る - kk-web