14
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

この記事では、TypeScriptにおける as const の概要や使いどころ、注意点などについてサンプルコードを交えながらまとめます。

as const とは?

TypeScriptの as const は、リテラル型をそのまま保持するための型アサーション(型の断定)です。

通常、配列やオブジェクトを定義すると、その中身はより広い型に推論されますが、as const を使うことで 中身の型をリテラルに固定し、さらに readonly にする ことができます。

▼ 例:配列の場合

.ts
const arr = [1, 2, 3];
// 推論: number[]

const fixedArr = [1, 2, 3] as const;
// 推論: readonly [1, 2, 3]

▼ 例:オブジェクトの場合

.ts
const obj = { role: "admin" };
// 推論: { role: string }

const fixedObj = { role: "admin" } as const;
// 推論: { readonly role: "admin" }

主な用途

固定された選択肢を型として定義したいときに非常に便利です。

例えば、色を選ぶフォームの選択肢や、APIが "red" | "green" | "blue" のような固定値(enum的な値)を返す場合に便利です。

.ts
const colors = ["red", "green", "blue"] as const;
// 推論: readonly ["red", "green", "blue"]

type Color = typeof colors[number];
// Color型: "red" | "green" | "blue"

この Color 型を使えば、UIでの選択やバリデーション、APIとの整合性を型で保証できます。

▼ 使用例1: セレクトボックスの選択値に使う

.ts
function onSelectColor(color: Color) {
  console.log(`選ばれた色は ${color} です`);
}

onSelectColor("red");   // ✅ OK
onSelectColor("yellow"); // ❌ エラー: 型 '"yellow"' を型 'Color' に割り当てることはできません。

▼ 使用例2: APIから受け取った色が有効か判定する

.ts
function isValidColor(value: string): value is Color {
  return colors.includes(value as Color);
}

const fromApi = "green";

if (isValidColor(fromApi)) {
  // fromApi の型はここで Color に絞られる
  console.log(`APIから受け取った色: ${fromApi}`);
} else {
  console.error("不正な色の値を受信しました");
}

typeof colors[number][number] について

  • typeof colors
    • colors 配列の型そのものを取得
    • as const を使用しているため、TypeScript は colorsreadonly ["red", "green", "blue"] という固定されたタプルとして推論
  • [number]
    • 配列やタプルの型に対して [number] をつける
    • 配列やタプルを数値のインデックス(例: colors[0]colors[1])でアクセスした場合に返されるすべての要素の型を結合したユニオンを作成

[number] がないと、typeof colorsreadonly ["red", "green", "blue"] となり、これは配列そのものの型です。

[number] を加えることで、TypeScript は「colors 配列に含まれる可能性のあるすべての要素の型」を抽出し、結果として "red" | "green" | "blue" というユニオン型を生成します。これにより、Color 型は「"red"、"green"、"blue" のいずれかの文字列」を表現できるようになります。

注意点

as const を使うと、配列やオブジェクトのプロパティは自動的に readonly になります。

.ts
const list = [1, 2, 3] as const;
list.push(4); // ❌ エラー: Property 'push' does not exist on type 'readonly [1, 2, 3]'

そのため、ミューテート(変更)する前提のデータには使えません。

Tips

as const に関する Tips を紹介します。

1. 毎回 as const を書くのが面倒? → const アサーションヘルパーの活用

as const は便利ですが、使うたびに毎回手で書くのは少し煩わしいと感じるかもしれません。
特にユニオン型を作るための配列を何度も定義するようなケースでは、次のように繰り返し as const を書くことになります。

.ts
const colors = ["red", "green", "blue"] as const;
const sizes = ["small", "medium", "large"] as const;
const roles = ["admin", "user", "guest"] as const;

このようなパターンが増えてくると、毎回 as const を書く手間や統一されていない記述が気になってきます。
そんなときは以下のようなユーティリティ関数を 1 つ定義しておくと、定数配列を簡潔かつ一貫性のある方法で定義できます。

.ts
// ユニオン型を得るための定数配列を定義するヘルパー関数
const defineConstArray = <T extends readonly string[]>(arr: T) => arr;

これを使えば、as const を意識せずに済みます。

.ts
const categories = defineConstArray(["news", "event", "release"]);
// 推論: readonly ["news", "event", "release"]

type Category = typeof categories[number];
// 型: "news" | "event" | "release"

2. バリデーションライブラリとの連携

as const を使って定義したユニオン型を、Zodなどのバリデーションライブラリでも活用できます。

as const を使えば、Zodのスキーマと型を一箇所で定義できます。

.ts
import { z } from "zod";

// まず定数配列を定義
const colors = ["red", "green", "blue"] as const;

// スキーマは配列から直接生成できる
const ColorSchema = z.enum(colors);

// 型もスキーマから取得可能(または typeof colors[number] でもOK)
type Color = z.infer<typeof ColorSchema>;

z.enum(colors) は、readonly ["red", "green", "blue"] の配列を受け取って Zod の enum スキーマを作ります。型 Color"red" | "green" | "blue" として推論され、フォーム入力や API レスポンスの型としても活用できます。
こうすることで、定義の重複を避けつつ、型とバリデーションの整合性が取れるようになります。

まとめ

as const は、TypeScriptでリテラル型を固定し、readonly な定数として扱うための便利な機能です。配列やオブジェクトに使うことで、ユニオン型の生成や型安全なバリデーションが可能になり、フォーム選択肢やAPIレスポンスの扱いを強力にサポートします。
as const を毎回書くのが煩雑な場合はユーティリティ関数で簡略化でき、Zodと組み合わせればスキーマ定義と型定義を一元化することも可能です。型の整合性を保ちながら効率的にコーディングしたいときに活用したいテクニックです。

参考

関連記事

14
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?