如何在TypeScript接口中递归推导类型参数?
TypeScript 递归推导嵌套节点的类型参数
问题分析
需要定义支持无限嵌套的结构,要求每个节点的value类型必须与同节点fn的参数类型一致,且子节点可拥有独立类型,不能强制所有节点共用同一类型。
解决方案
1. 递归泛型接口定义
将Foo定义为递归泛型接口,让children属性接受任意类型的Foo节点数组,这样每个子节点可根据自身value自动推断类型:
interface Foo<T = unknown> { value: T; fn: (value: T) => void; children?: Foo[]; }
这里T = unknown是默认泛型参数,未显式指定时,TypeScript会根据value的实际值自动推导T的具体类型。children使用Foo[]而非Foo<T>[],避免子节点类型被当前节点的T限制,允许每个子节点拥有独立类型。
2. 类型推断辅助函数
保留原有的makeFoo函数,它会自动推导根节点类型,同时子节点的类型也会被TypeScript正确识别:
function makeFoo<T>(foo: Foo<T>): Foo<T> { return foo; } // 使用示例 const foo = makeFoo({ value: 'abc', fn: (value) => { /* value 类型自动推断为 string */ }, children: [ { value: 123, fn: (value) => { /* value 类型自动推断为 number */ } }, { value: false, fn: (value) => { /* value 类型自动推断为 boolean */ } }, // 支持无限嵌套 { value: { name: 'test' }, fn: (value) => { /* value 类型自动推断为 { name: string } */ }, children: [ { value: [1, 2, 3], fn: (value) => { /* value 类型自动推断为 number[] */ } } ] } ] });
效果验证
上述代码中:
- 根节点
value为字符串,fn参数自动推断为string - 第一层子节点分别对应
number、boolean类型,fn参数类型完全匹配 - 深层嵌套的子节点也能正确推导复杂类型(如对象、数组)
原理说明
递归泛型接口的核心是允许children属性引用自身类型,且不限制泛型参数的一致性。TypeScript的类型推断系统会遍历整个嵌套结构,为每个节点的value和fn参数推导出最精确的类型,同时保持结构的递归性。
内容的提问来源于stack exchange,提问作者Lehks
相关产品推荐
相关产品推荐

