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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 19:05:00