Kodokon kodokon.com

Enum と const アサーション: 現代的な代替手段

enum の限界を理解し、as const で凍結した定数から型を導出しましょう。

7 分 · 3 問

このレッスンを Kodokon で開く

enum は言語の初期からある機能で、多くのコードベースで出くわすでしょう。名前付き定数を1つの型のもとにまとめ、値としても注釈としても使えます。

TYPESCRIPT
enum Role {
  User = "USER",
  Admin = "ADMIN",
}

function canDelete(role: Role): boolean {
  return role === Role.Admin;
}
典型的な文字列 enum

しかし現代のエコシステムは enum から離れつつあります。enum は JavaScript には存在しない構文です。コンパイラは実行時にオブジェクトを生成するため、一部のツールを複雑にし、erasableSyntaxOnly オプションとは互換性がありません。代替手段は、as const で凍結した素のオブジェクトで、そこから型を導出します。

TYPESCRIPT
const ROLES = {
  User: "USER",
  Admin: "ADMIN",
} as const;

type Role = (typeof ROLES)[keyof typeof ROLES];

function canDelete(role: Role): boolean {
  return role === ROLES.Admin;
}
導出型を持つ as const オブジェクト、現代的な等価物

as const は配列にも効きます。各要素は読み取り専用のリテラルになり、(typeof SIZES)[number] は値のユニオンを生み出します。単一の信頼できる情報源が、実行されるコードと型の両方を支えます。

TYPESCRIPT
const SIZES = ["sm", "md", "lg"] as const;

type Size = (typeof SIZES)[number];

function isSize(value: string): value is Size {
  return (SIZES as readonly string[]).includes(value);
}
as const 配列: 実行時には反復可能、型レベルではユニオン

理解度チェック

このレッスンの要点をしっかり覚えているか確認しましょう。

  1. enum と as const で凍結したオブジェクトを分ける大きな違いは何ですか?
    • enum はコードを生成する TypeScript 固有の構文だが、as const オブジェクトは素の JavaScript のままである
    • as const オブジェクトは実行時に遅い
    • enum は数値しか含められない
  2. 配列 ['sm', 'md'] に適用したとき、as const は何を生み出しますか?
    • string[]
    • リテラル型の読み取り専用タプル
    • Array<'sm' | 'md'> 型の可変配列
    • コンパイルエラー
  3. as const で凍結した ROLES オブジェクトの値のユニオンを得るにはどうしますか?
    • keyof typeof ROLES
    • (typeof ROLES)[keyof typeof ROLES]
    • typeof ROLES