IT-Q

上の routes で、routes.home の型を "/" というリテラル型のまま残したい。どう書きますか。

{ ... } as const satisfies Record<string, string> と書きます。as const で値をリテラル型と readonly に固定し、satisfies で形を検査します。値から型のユニオンも作れます。

面接官が見ているのはas const と satisfies を組み合わせられるか。

これは「const routes: Record<string, string> = { home: "/", about: "/about" } と書いたら、routes.contact のような存在しないキーでもエラーにならなくなりました。どうしますか。」への追撃質問です。

よくある答えと、面談でどう見られるか

  • { ... } as const satisfies Record<string, string> と書く
    その通りです。as const でリテラル型と readonly に固定し、satisfies で形を検査します。
  • satisfies Record<string, "/" | "/about"> と書く
    検査は厳しくなりますが、値を足すたびに型も書き換える必要があります。値から型を導く方が楽です。
  • satisfies だけで、値は自動でリテラル型になる
    satisfies は型を広げませんが、オブジェクトのプロパティの値は通常 string に広がります。as const が要ります。
  • routes を let で宣言する
    let にすると、むしろ型は広がる方向です。

模範解答

as const と satisfies を組み合わせます。

  const routes = { home: "/", about: "/about" } as const satisfies Record<string, string>

as const で、値をリテラル型("/" や "/about")のまま固定し、readonly にします。そのうえで satisfies で、Record<string, string> の形に合っているかを検査します。

こうすると routes.home の型は "/" になり、(typeof routes)[keyof typeof routes] で "/" | "/about" というユニオン型も作れます。値を1か所に書くだけで、検査と型の両方がそろいます。

対象: TypeScript 5.x〜7.0 照合した一次資料: 公式ドキュメント 照合: 2026-10-25 最終更新: 2026-10-25
お使いの版で挙動が違う場合があります。誤りに気づいたらこの解説を報告するから教えてください。