as const satisfies の使い所

● 例1 (別に as const satisfies を使わなくても良い例)

問題1 . エラーになる例

type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";

type Route = {
  path: string;
  method: HttpMethod;
};

// ❌ widening が起こる
const routes1: Record<string, Route> = {
  getUser: { path: "/users/:id", method: "GET" },
  createUser: { path: "/users", method: "POST" },
};

routes1.getUser.method // 型: HttpMethod (Union型)

// 関数で使おうとすると...
function handleRequest(method: "GET" | "POST") {
  // ...
}
handleRequest(routes1.getUser.method); // ❌ エラー!
// HttpMethod 型は "GET" | "POST" | "PUT" | "DELETE" なので代入できない

解決策1 . as const satisfies を使う場合

// ✅ widening を抑止
const routes2 = {
  getUser: { path: "/users/:id", method: "GET" },
  createUser: { path: "/users", method: "POST" },
} as const satisfies Record<string, Route>;

routes2.getUser.method // 型: "GET" (リテラル型)
handleRequest(routes2.getUser.method); // ✅ OK!

解決策2 . as const satisfies を使わない場合(使わなくてもいけます)

// 型 "GET" | "POST" を
// 型 Extract<HttpMethod,"GET" | "POST"> にするだけで ✅OK
function handleRequest(method: Extract<HttpMethod,"GET" | "POST">) {
  // ...
}

● 例2 (as const satisfies を使うべき例)

type Config = { apiUrl: string; timeout: number; features: {

analytics: boolean;
darkMode: boolean;

}; };

// ❌ これはダメ(型チェックされない) const config1 = { apiUrl: "https://api.example.com", timeout: 3000, features: {

analytics: true,
darkMood: true, // ← typo! でもエラーにならない

}, } as const;

// ❌ これもダメ(readonlyにならない) const config2: Config = { apiUrl: "https://api.example.com", timeout: 3000, features: {

analytics: true,
darkMode: true,

}, }; config2.timeout = 5000; // ✅ 変更できてしまう

// ✅ readonly + 型チェック const config3 = { apiUrl: "https://api.example.com", timeout: 3000, features: {

analytics: true,
darkMood: true, // ❌ エラー! typoが検出される

}, } as const satisfies Config;

config3.timeout = 5000; // ❌ エラー! readonlyなので変更できない

No.2700
12/19 11:19

edit