2026.02.05TypeScript
satisfiesとasの使い分けを理解する
はじめに
TypeScript 4.9 で導入された satisfies 演算子は、型の安全性を保ちながら値の型推論を維持できる強力な機能です。
既存の as との違いを正しく理解し、使い分けることが重要です。
as の問題点
as はダウンキャストもアップキャストも許容するため、型安全性が失われるケースがあります。
type Color = "red" | "green" | "blue";
// as を使うと、誤った値でもコンパイルが通ってしまう
const palette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [0, 0, 255],
} as Record<Color, string | number[]>;
// palette.green の型は string | number[] になる
// 実際は string なのに number[] のメソッドも呼べてしまう
satisfies の登場
satisfies は「この値が型を満たすかチェックするが、推論された型はそのまま保持する」という動作をします。
type Color = "red" | "green" | "blue";
const palette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [0, 0, 255],
} satisfies Record<Color, string | number[]>;
// palette.green の型は string(推論が保持される)
palette.green.toUpperCase(); // ✅ OK
// palette.red の型は number[](推論が保持される)
palette.red.map((v) => v * 2); // ✅ OK
実務での使い分け
satisfies を使うべきケース
- 設定オブジェクトの型チェック
type Config = {
apiUrl: string;
timeout: number;
retries: number;
};
export const config = {
apiUrl: "https://api.example.com",
timeout: 5000,
retries: 3,
} satisfies Config;
// config.apiUrl は "https://api.example.com" リテラル型
- Record のキー網羅チェック
type Status = "idle" | "loading" | "success" | "error";
const statusLabel = {
idle: "待機中",
loading: "読み込み中",
success: "完了",
error: "エラー",
} satisfies Record<Status, string>;
// キーが足りないとコンパイルエラー
as を使うべきケース
- DOM 要素の型アサーション
const input = document.getElementById("email") as HTMLInputElement;
- API レスポンスの型付け(ただしバリデーションと併用すべき)
const data = (await res.json()) as ApiResponse;
まとめ
| 観点 | as | satisfies |
|------|------|-------------|
| 型チェック | 弱い(強制キャスト) | 強い(型を満たすか検証) |
| 推論の保持 | 失われる | 保持される |
| 主な用途 | DOM操作、外部データ | 設定、定数定義 |
基本方針として、まず satisfies を検討し、as は型推論が不可能な場面でのみ使うのがおすすめです。