TypeScript通用选项接口创建问题:只读数组赋值报错
解决方案
你的核心问题是只读元组与可变数组的类型不兼容:as const会把数组标记为只读元组类型readonly ["yes", "no", "maybe"],但你的泛型里options定义的是可变数组Array<list>,两者无法直接赋值。同时可以优化泛型设计,让类型约束更精准。
下面提供三种可行方案:
方案1:将泛型的options改为只读数组类型
直接修改泛型定义,让options接受只读数组,这样就能直接复用these_options:
export type GenericListOfOptions<list> = { type: 'list', name: string, value: list, options: readonly list[], // 改为只读数组类型 } // 定义选项: const these_options = ['yes', 'no', 'maybe'] as const; // 基于泛型类型定义特定选项类型: type MySpecificOptions = GenericListOfOptions<typeof these_options[number]> // 使用该类型创建选项对象: let my_options: MySpecificOptions = { type: 'list', name: 'am i going to the gym?', value: 'no', options: these_options, // 现在类型完全匹配 }
优点:保留原数组的只读特性,避免意外修改选项列表,适合不需要动态修改options的场景。
方案2:将只读数组转换为可变数组
如果需要options是可变数组(后续可能修改),可以通过展开运算符将只读元组转换为普通数组:
export type GenericListOfOptions<list> = { type: 'list', name: string, value: list, options: Array<list>, } const these_options = ['yes', 'no', 'maybe'] as const; type MySpecificOptions = GenericListOfOptions<typeof these_options[number]> let my_options: MySpecificOptions = { type: 'list', name: 'am i going to the gym?', value: 'no', options: [...these_options], // 展开为可变数组 }
优点:保持options的可变性,适合需要动态增删选项的场景。
方案3:优化泛型设计,绑定整个数组类型
让泛型直接接受数组类型,而不是元素的联合类型,这样能更精准地约束options必须是指定的具体选项列表,而不是任意包含这些元素的数组:
export type GenericListOfOptions<T extends readonly string[]> = { type: 'list', name: string, value: T[number], // 从数组类型中提取元素类型 options: T, // 直接使用原数组的类型 } const these_options = ['yes', 'no', 'maybe'] as const; type MySpecificOptions = GenericListOfOptions<typeof these_options> let my_options: MySpecificOptions = { type: 'list', name: 'am i going to the gym?', value: 'no', options: these_options, // 完全匹配原数组类型 }
优点:类型约束更严格,确保options的结构和原数组完全一致,避免出现重复元素或顺序错误的情况,最贴合你“复用these_options数组”的需求。
内容的提问来源于stack exchange,提问作者Ólavur Nón
相关产品推荐
相关产品推荐

