You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何定义仅含原始类型或自身递归对象的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,提问作者Макс Кудрин

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:02:34