オブジェクトリテラルの末尾に as const を記述すればプロパティが readonly でリテラルタイプで指定した物と同等の扱いになります。
literal 型で
type NameType = 'hoge' | 'fuga'; interface OptionType { id: number; name: NameType; } const options: OptionType[] = [{ id: 1, name: 'hoge' as NameType }]; // こっちの方がシンプル const options: OptionType[] = [{ id: 1, name: 'hoge' as const }];
interface ComponentOptionType<T extends string> { id: T; label: string; } interface Props<T extends string> { value: ComponentOptionType<T>; options: ComponentOptionType<T>[]; } function component<T extends string>({ value, options }: Props<T>) { return { value, options }; } type OptionType = 'hoge' | 'fuga'; const options: ComponentOptionType<OptionType>[] = [ { id: 'hoge', label: 'ホゲ' }, { id: 'fuga', label: 'フガ' }, ]; const result = component({ value: options[0], options: options }); console.log('result:', result.value);
string を extends し、string 以外を受け付けないようにしている。
// VSCode コマンドパレット 「ts server」入力から、再起動でいける