上の 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
お使いの版で挙動が違う場合があります。誤りに気づいたらこの解説を報告するから教えてください。