TypeScriptのas constは、オブジェクトや配列の値とプロパティをreadonlyおよびリテラル型に変換します。これにより、厳密な型付けが実現され、値は基本型に「拡張」されず、特定の値を保持します。
例:
const a = { status: 'success' }; // 型: { status: string } const b = { status: 'success' } as const; // 型: { readonly status: "success" }
利点:
欠点/特徴:
質問: 文字列の配列にas constを使用すると、その型はどうなり、通常のstring[]として渡すことはできますか?
回答: 型はreadonly ["a", "b", "c"]になります。つまり、readonly制約を持つリテラル型のタプルです。この配列はstring[]型と互換性がなく、可変の文字列配列を期待する場所に直接渡すことはできません。
const arr = ['a', 'b', 'c'] as const; // readonly ["a", "b", "c"] function acceptsStrings(x: string[]) {} acceptsStrings(arr); // エラー!型互換性なし
物語
プロジェクト: actionTypesのリストをas constで定数配列として保持し、その後string[]を待つ関数に渡そうとしました。型エラーが発生し、
.slice()または[...arr]を使って明示的に変換する必要がありました。
物語
プロジェクト: Reduxのマイクロフレームワークで、action.typeの型をas constを使ってリテラルとして定義しました。switch-caseを実装する際、厳密な型付けを忘れ、すべての可能なリテラルを処理しなかったため、exhaustive checkが作動せず—新しいアクションを追加するまでエラーは発生しませんでした。
物語
プロジェクト: APIエンドポイントを自動生成する際に、そのキーをas const配列で記述しました。これらのキーを通常のRecord<string, ...>のインデックスとして使用しようとしたところ、型の不整合により失敗し、変換を追加するか、配列のキーの型を明示的に使用する必要がありました。