未経験でも気軽に!サブスク型プログラミングスクール【Freeks】
困ってた自分に届けたい話
TypeScript定数を定義して、あとからそのまま型にも使いたいとき。
「書いた値を使って型をつくったはずなのに、string型になってる…」
「え、これユニオン型じゃないの?なんで?」
って何回もなった。
毎回型を別で書き直すの、地味に面倒くさいしミスも増える。
そんなときに知った as const、たった一言で「値=型」になって、ほんとに楽になった。

この記事は、同じように困っていた方への備忘録兼シェアとして書いています。
as constとは?
as const は TypeScript の構文で、値を“そのまま”の形で型として固定するための書き方です。
const COLORS = ["red", "blue", "green"];このとき、COLORS の型は string[] になります。
つまり、 "yellow" など本来想定していない値も通ってしまう可能性があります。
しかし as const を使うと
const COLORS = ["red", "blue", "green"] as const;これだけで、型はこうなります。
readonly ["red", "blue", "green"]中身の "red" | "blue" | "green" を型として使えるようになります。この状態になると、「この配列の中には、決まった値しか入っていない」と型で表現できるようになります。
「型」ってそもそも何?
TypeScriptでは、以下のような基本的な型(プリミティブ型)があります。
| 型名 | 意味 | 例 |
|---|---|---|
string | 文字列 | "hello" |
number | 数値 | 42 |
boolean | 真偽値 | true / false |
string[] | 文字列の配列 | ["a", "b"] |
多くの人は「型=stringやnumberのこと」と思っているはずです。
でも、TypeScriptには他にも重要な型の考え方があります。
リテラル型とユニオン型の違い
リテラル型:特定の値だけを許す型
const color: "red" = "red"; // "red" だけOKユニオン型:複数の値の中からどれか1つを許す型
type Color = "red" | "blue" | "green";つまり、リテラル型は1つだけOK、ユニオン型は”いくつかから1つ選ぶ”感じです。
配列で使う as const
たとえば、次のようなコードがあります。
const COLORS = ["red", "blue", "green"] as const;
type Color = typeof COLORS[number];
// → "red" | "blue" | "green"📓 説明
as const:配列の中身を変更できないようにし、”red” などの固定値として扱うtypeof COLORS[number]:配列内の要素を全部取り出して、型にする
これで Color型には “red”、”blue”、”green” だけが使えるようになります。
🔍 なぜnumberを使うの?
type Color = typeof COLORS[number];この number は「配列の中のすべての値を取り出す」という意味です。配列は COLORS[0], COLORS[1] のように数字(=number)でアクセスします。
だから COLORS[number] と書くと、「すべてのインデックス番号に対応する値=全要素」を指すことになります。これは TypeScript の決まり文句なので、覚えてしまえばOKです。
オブジェクトで使う as const
const STATUS = {
OK: 200,
NOT_FOUND: 404,
} as const;
type StatusCode = typeof STATUS[keyof typeof STATUS];
// → 200 | 404📓 説明
as const:オブジェクトの中身(200 や 404)を固定するtypeof STATUS[keyof typeof STATUS]:すべての値をまとめて型にする
結局何が便利なの?
as const を使うと、値と型の“二重管理”が不要になります。
たとえば、ボタンの種類を定義しておきたいとき:
const BUTTON_TYPES = ["primary", "secondary", "danger"] as const;
type ButtonType = typeof BUTTON_TYPES[number];このようにしておけば:
- 値としてボタンタイプを配列で定義
- 型としてもそのまま使える(”primary” | “secondary” | “danger”)
あとから値を追加・削除しても、型も一緒に変わるので、管理がラクになってミスも防げるんです。
as const のメリット
❌ as const なし
const roles = ["admin", "user"];
type Role = typeof roles[number]; // → string"admin" でも 定義していない "manager" でも通ってしまいます。
✅ as const あり
const roles = ["admin", "user"] as const;
type Role = typeof roles[number]; // → "admin" | "user"型が限定され、間違った値を弾けるようになります。

おつかれさまでした!


コメント