TypeScript | 基礎文法:変数・基本型 – const時の型の固定

TypeScript
スポンサーリンク

const は「値」と「型」をその場で固定する宣言

const は「再代入できない変数」を宣言するキーワードですが、TypeScriptでは型の固定のされ方にも特徴があります。
const で宣言した瞬間に、「この変数にはこの値(=この型)しか来ない」という前提がかなり強くなります。

const name = "Taro";
TypeScript

この1行で、
name は再代入できない」
name は文字列で、しかも "Taro" という値で固定されている」
という情報を TypeScript は持ちます(リテラル型として扱われるイメージ)。

let と違って、「あとで別の値が入るかもしれない」という可能性がないので、コンパイラはより“固い”型として扱えるわけです。


let と const の型推論の違い

let は「将来変わるかも」を前提にした型

let の場合、初期値から型は推論されますが、「将来別の値が入るかもしれない」という前提で、少し広めに扱われます。

let color = "red"; // 型は string と推論される

color = "blue";    // OK
color = "green";   // OK
// color = 123;    // エラー(number はダメ)
TypeScript

"red" という値から始まっていますが、「将来 "blue""green" になるかもしれない」ので、型としては「string 全体」と見なされます。

const は「この値そのもの」を型として扱える

一方 const の場合、値が変わらないので、もっと狭い型——リテラル型として扱えます。

const color = "red"; // 型は "red" という文字列リテラル型

// color = "blue";  // そもそも再代入がエラー
TypeScript

ここでのポイントは、「color の型は string ではなく "red"」ということです。
つまり、「color は ‘red’ 以外になり得ない」という情報を、型レベルで持てるようになります。

この「リテラル型として固定される」という性質が、const 時の型の固定の一番おいしいところです。


const とオブジェクト・配列の型の固定

参照は固定されるが、中身は変えられる

まず大事な前提として、const は「再代入を禁止する」だけであって、「中身の変更まで禁止する」わけではありません。

const user = {
  name: "Taro",
  age: 20
};

user.name = "Hanako";  // OK(プロパティの変更)
// user = { name: "Jiro", age: 30 }; // エラー(再代入)
TypeScript

user という「箱」がどのオブジェクトを指しているかは固定されますが、そのオブジェクトのプロパティは変更できます。
型としては、user の型は { name: string; age: number } のように推論され、そのプロパティに対して型チェックが効き続けます。

as const で「中身まで完全固定」する

「このオブジェクトの中身も含めて、全部リテラルとして固定したい」というときは、as const を使います。

const user = {
  name: "Taro",
  age: 20
} as const;
TypeScript

こうすると、型は次のようなイメージになります。

{
  readonly name: "Taro";
  readonly age: 20;
}
TypeScript

プロパティも readonly になり、値も "Taro"20 に固定されます。
設定値や定数テーブルのように、「絶対に変わらない前提のデータ」を表現するときにとても強力です。


const で型を固定することのメリット

「変わらない前提」を型に刻める

const を使う一番のメリットは、「この値は変わらない」という前提を、人間にもコンパイラにも伝えられることです。

const TAX_RATE = 0.1;
TypeScript

この1行で、
「TAX_RATE は number で、0.1 という値で固定」
「途中で誰かが書き換えることはできない」
という保証が得られます。

もし let TAX_RATE = 0.1; と書いていたら、どこかで TAX_RATE = 0.08; と上書きされる可能性があります。
const にしておけば、そういうバグはコンパイル時に止められます。

リテラル型として扱えることで、より強い型チェックができる

const で固定されたリテラル型は、ユニオン型などと組み合わせるとさらに威力を発揮します。

const THEME_LIGHT = "light" as const;
const THEME_DARK = "dark" as const;

type Theme = typeof THEME_LIGHT | typeof THEME_DARK;

let theme: Theme = THEME_LIGHT; // "light" | "dark" のどちらか
// theme = "blue"; // エラー
TypeScript

ここでは、"light""dark" という具体的な値を型として扱い、「この2つ以外は許さない」というルールを作っています。
const で値を固定しているからこそ、こういう「値レベルの型」を安全に使えるわけです。


初心者がまず意識すべき const 時の型の固定の感覚

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

const で宣言した瞬間、その変数は「値も型もその場で固まる」。
「変わらない前提のもの」は、必ず const にする。
let は「本当に変える必要があるときだけ」にする。

この感覚が身につくと、
「どこが動く部分で、どこが固定の前提なのか」
がコードから自然と読み取れるようになります。

そして TypeScript は、その「前提」を型として理解し、再代入の禁止やリテラル型としての扱いを通じて、あなたの意図を守ってくれます。
const は、ただの「再代入禁止」ではなく、「設計の意図を型に刻むための道具」だと思って使ってみてほしい。

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