TypeScript | 基礎文法:変数・基本型 – as const の意味

TypeScript
スポンサーリンク

as const は「この値をそのままの形で固定して」と伝えるスイッチ

as const は、TypeScript に対してこう宣言するためのものです。
「この値は“変わらない前提”だから、できるだけそのままの形・そのままの値で扱ってほしい

具体的には、as const を付けると次のことが起こります。

  • 値が「広い型」ではなく「リテラル型」にまでギュッと絞られる
  • 配列やオブジェクトの場合、その中身が readonly(書き換え禁止)になる

つまり、「値」と「型」と「変更不可」の3つを一気に固める宣言as const です。

const arr = [1, 2, 3];
// 型: number[]

const arrFixed = [1, 2, 3] as const;
// 型: readonly [1, 2, 3]
TypeScript

同じ配列でも、as const を付けた瞬間に「意味のある定義」に変わります。


普通の const と as const の違いを具体例で見る

const だけの場合(まだ“ゆるい”状態)

まずは const だけのとき。

const colors = ["red", "green", "blue"];
// 型: string[]
TypeScript

ここで TypeScript が知っているのは「文字列の配列」ということだけです。
中身が "red" なのか "yellow" なのかまでは、型としては区別していません。

colors.push("yellow"); // 型的にはOK
TypeScript

const は「変数そのものの再代入」を禁止するだけで、
配列の中身やオブジェクトのプロパティは、まだ変更可能です。

as const を付けた場合(“ガチガチに固定”された状態)

同じものに as const を付けると、こう変わります。

const colors = ["red", "green", "blue"] as const;
// 型: readonly ["red", "green", "blue"]
TypeScript

ここで起きていることは、

  • 配列の要素が "red" | "green" | "blue" という文字列リテラル型に固定される
  • 配列自体が readonly になり、push や書き換えができなくなる

という、「定義した通りの値・順番・個数を、そのまま型として扱う」状態です。

// colors.push("yellow"); // エラー
// colors[0] = "black";   // エラー
TypeScript

「この配列は“定義そのもの”が意味を持つ。あとから変えられたら困る」
というときに、as const はぴったりハマります。


オブジェクトに対する as const の効果

プロパティが「リテラル型+readonly」になる

オブジェクトでも同じです。

const config = {
  env: "production",
  timeout: 5000
} as const;
TypeScript

このときの型は、イメージとしてはこうなります。

{
  readonly env: "production";
  readonly timeout: 5000;
}
TypeScript

つまり、

  • env"production" 以外にならない
  • timeout5000 以外にならない
  • どちらも再代入できない

という、かなり“固い”オブジェクトになります。

// config.env = "dev";     // エラー
// config.timeout = 1000;  // エラー
TypeScript

設定値や定数テーブルのように、「ここに書いた値そのものが仕様だ」というデータには、as const がとても相性がいいです。


as const の一番おいしい使い方:配列から「選べる型」を作る

as const が実務で一番輝くのは、「選択肢の配列」から「選べる値の型」を作るときです。

const COLORS = ["red", "green", "blue"] as const;
// 型: readonly ["red", "green", "blue"]

type Color = (typeof COLORS)[number];
// Color は "red" | "green" | "blue"
TypeScript

typeof COLORSreadonly ["red", "green", "blue"] というタプル型になり、
[number] を付けることで「その配列の要素の型」、つまり "red" | "green" | "blue" を取り出せます。

これで、

let c: Color;

c = "red";    // OK
c = "blue";   // OK
// c = "yellow"; // エラー
TypeScript

という、「この3色だけ」という型を簡単に作れます。
UI の選択肢、API の固定値、状態の種類などで、めちゃくちゃよく使うパターンです。


readonly と as const の違いも軽く整理しておく

readonlyas const は似た匂いがするので、ここで一度整理しておきます。

  • readonly は「型の中で“変更禁止”を指定する」
  • as const は「値の末尾に書いて、“リテラル型+readonly”に一気に変換する」

たとえば:

type User = {
  readonly id: number;
  name: string;
};

const user: User = { id: 1, name: "Taro" };
// user.id = 2;   // エラー(readonly)
// user.name = "Jiro"; // OK
TypeScript

これは「型側に readonly を書いている」パターン。
一方で:

const user = {
  id: 1,
  name: "Taro"
} as const;
TypeScript

これは「値側に as const を書いて、
id: 1(リテラル型)かつ readonly
name: "Taro"(リテラル型)かつ readonly
にしている」パターンです。


初心者向け as const の実践的な感覚

難しいことを全部抜きにして、まずはこう覚えておくといいです。

  • 「この配列・オブジェクトは“定義そのもの”が意味を持つ。変えたくない」
    as const を付ける
  • 「この配列から“選べる値の型”を作りたい」
    const OPTIONS = [...] as consttype Option = (typeof OPTIONS)[number];
  • 「定数の値と型をズラしたくない」
    const X = "foo" as const; type XType = typeof X;

as const は、
「この値、本当に固定なんだよ」というあなたの設計意図を、
TypeScript に全力で理解させるためのスイッチです。

VSCode で、as const を付けたり外したりして、
ホバーしたときの型表示がどう変わるかを眺めてみてほしい。
それを何回か繰り返すだけで、「ああ、これは“値をそのまま型にするボタン”なんだな」という感覚が、ちゃんと自分のものになっていきます。

タイトルとURLをコピーしました