TypeScript中如何定义支持递归父子结构的泛型类型?
实现递归可嵌套的Widget类型
问题背景
需要定义支持任意子节点递归嵌套的Widget类型,避免编写Widget<Widget<Widget<Widget>>>这类冗余的多层嵌套泛型声明,单次类型声明即可支持无深度限制的递归使用。
原有定义存在类型校验问题:声明为Widget<Widget>类型的对象,内层节点的children仅允许传入string类型,无法继续嵌套Widget结构,问题代码如下:
type Widget<T = string> = { children?: T[] } const foo: Widget<Widget> = { children: [ { // 类型报错:此处仅允许string类型,不支持Widget类型 children: ['A', 'B'] } ] };
问题原因:传入
Widget<Widget>时,内层的Widget未指定泛型参数,会默认使用string作为泛型入参,整体等价于Widget<Widget<string>>,因此内层节点的children类型为string[],无法继续嵌套Widget结构。
正确实现
修改类型定义,在children的类型联合中加入自引用的Widget<T>,类型系统会自动递归识别任意深度的嵌套结构,无需手动叠加泛型:
type Widget<T = string> = { children?: (T | Widget<T>)[] }
修改后直接使用Widget作为类型即可,既支持默认的string类型叶子节点,也支持无限制层级的子节点嵌套:
const foo: Widget = { children: [ { children: ['A', 'B', { children: ['C', { children: ['D', 'E', { children: ['F'] }] }] }] } ] };
如果需要自定义叶子节点类型,正常传入泛型参数即可,例如Widget<number>代表叶子节点为数字、支持任意深度嵌套的组件类型。
内容的提问来源于stack exchange,提问作者Mohamad Shiralizadeh
相关产品推荐
相关产品推荐

