如何定义仅含原始类型或自身递归对象的TypeScript类型?
如何定义仅包含原始类型或同结构嵌套对象的TypeScript类型?
我想要创建一个对象类型,要求它的属性只能是原始类型(string、number、boolean),或者是和自身结构完全一样的嵌套对象。比如下面的示例里,部分属性就不符合要求:
const obj: DesiredType = { correctProp1: 'string', correctProp2: 123, correctProp3: true, wrongProp4: [1, 2, 3], // 数组不允许 prop5: { wrongProp1: () => {}, // 函数不允许 wrongProp2: [1, 2, 3], // 数组不允许 correctProp3: 'other string' } }
我不想用Record<string, any>,因为它啥类型都能塞;Record<string, string | number | boolean | Record<string, any>>也不行,第二层开始又放开任意类型了。
我试了下面的写法,结果报ts(2456)错误:类型别名“PrimitiveOrObject”循环引用自身。
type PrimitiveOrObject = string | number | boolean | Record<string, PrimitiveOrObject>; // ts(2456) 错误 type DesiredType = Record<string, PrimitiveOrObject>;
请问能不能创建符合要求的类型别名?
当然可以,TypeScript 3.7及以上版本已经支持递归类型别名,你之前的写法本质是对的,报错大概率是因为用了低于3.7的TS版本。如果版本没问题,也可以换两种方式实现:
方案1:递归类型别名(TS 3.7+)
直接简化你的写法,确保TS版本达标:
type Primitive = string | number | boolean; type DesiredType = Record<string, Primitive | DesiredType>;
这样DesiredType就表示:每个属性的值要么是原始类型,要么是另一个DesiredType对象,完全符合你的需求。
方案2:用Interface实现递归
如果你的TS版本较低,用interface更稳妥,因为interface天生支持递归结构:
type Primitive = string | number | boolean; interface DesiredType { [key: string]: Primitive | DesiredType; }
验证效果
用上面任意一种定义后,你示例里的错误属性都会被TS精准报错:
wrongProp4: [1, 2, 3]:数组不属于允许的类型wrongProp1: () => {}:函数不在允许范围内wrongProp2: [1, 2, 3]:同样数组类型不被接受
而正确的属性则能顺利通过类型检查。
内容的提问来源于stack exchange,提问作者Макс Кудрин
相关产品推荐
相关产品推荐

