TypeScript中如何限制Question的default为options内的字面量值?
约束TypeScript中Question类型的default属性必须属于options数组元素
现有如下TypeScript类型定义:
type Option = 'a' | 'b' | 'c' | 'd' type Question = { message: string; options: Option[]; default: Option // 无法关联到当前实例的options }
希望default属性必须是当前question.options数组中包含的选项之一。比如下面的q2中default: 'a'应该报错,因为'a'不在['c', 'd']里:
const q1: Question = { message: 'first question', options: ['a', 'b'], default: 'a' } const q2: Question = { message: 'second question', options: ['c', 'd'], default: 'a' // 期望此处报错 }
解决方案
通过泛型绑定options和default的类型关联,修改Question类型定义为泛型类型,让它依赖于具体的选项子集:
type Option = 'a' | 'b' | 'c' | 'd' // 泛型T约束为Option的子集 type Question<T extends Option> = { message: string; options: T[]; default: T; // 此时default必须是T类型,即options数组的元素类型 }
使用时不需要显式指定泛型参数,TypeScript会自动从options数组推断出T的类型:
// 正常通过:T被推断为'a' | 'b',default是'a'符合要求 const q1: Question = { message: 'first question', options: ['a', 'b'], default: 'a' } // 报错:类型'"a"'不能赋值给类型'"c" | "d"' const q2: Question = { message: 'second question', options: ['c', 'd'], default: 'a' }
如果需要更严格的约束(比如防止options数组被后续修改导致类型不一致),可以将options设为只读数组:
type Question<T extends Option> = { message: string; options: readonly T[]; default: T; }
内容的提问来源于stack exchange,提问作者Daniel Reina
相关产品推荐
相关产品推荐

