如何在TypeScript中结合对象/数组与递归类型?
解决递归联合类型定义问题
可行的类型定义方案
如果使用TypeScript 3.7及以上版本,直接用递归类型别名就能实现需求,无需借助interface:
type Foo = ({ bar: string } & Record<string, Foo>) | Foo[];
这个类型的含义是:
- 要么是包含
bar字符串属性,且其余任意字符串键对应值均为Foo类型的对象; - 要么是由
Foo类型组成的数组。
旧写法报错原因解析
- type循环引用问题:旧版本TypeScript(3.7之前)不支持直接递归的类型别名,升级TS版本即可解决该问题。
- interface扩展联合类型报错:你尝试用
interface Foo extends ArrayOrRecord时,ArrayOrRecord是联合类型(Atom | Array<Atom>),而TypeScript的interface仅能扩展对象类型或具有静态已知成员的交叉类型,联合类型不符合要求,因此抛出An interface can only extend an object type or intersection of object types with statically known members错误。
兼容旧版本TS的替代方案
若无法升级TS版本,可通过interface结合交叉类型实现:
interface FooBase { bar: string; [key: string]: Foo; } interface FooArray extends Array<Foo> {} type Foo = FooBase | FooArray;
通过FooBase定义对象结构,FooArray定义数组结构,最后用联合类型组合成Foo,同样满足递归需求。
内容的提问来源于stack exchange,提问作者Vytska
相关产品推荐
相关产品推荐

