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

TypeScript如何从泛型数组中自动提取嵌套类型?

解决方案

要实现init函数参数的自动类型推导,核心是让TypeScript将dependencies识别为元组类型,并从每个Resource元素中提取其泛型参数。以下是针对两种构造函数结构的具体实现:

先定义基础Resource类

首先我们需要一个带有泛型的Resource基类,后续的推导都基于这个结构:

class Resource<T> {
  constructor(private readonly value: T) {}
  // 假设存在获取资源值的方法,用于在init中传递参数
  getValue(): T {
    return this.value;
  }
}

结构1:构造函数接收分开的dependencies和initFunction

利用元组推断和映射类型,让TS自动推导init的参数类型:

class ResourceContainer1 {
  constructor<
    // 泛型D表示dependencies的元组类型,每个元素是Resource实例
    D extends Resource<any>[]
  >(
    // 使用[...D]强制TS将数组解析为元组,保留每个元素的具体类型
    dependencies: [...D],
    // 从元组D的每个元素中提取Resource的泛型类型,组成init的参数元组
    init: (...args: { [K in keyof D]: D[K] extends Resource<infer T> ? T : never }) => void
  ) {
    // 转换dependencies为对应类型的参数元组,调用init
    const args = dependencies.map(dep => dep.getValue()) as { [K in keyof D]: D[K] extends Resource<infer T> ? T : never };
    init(...args);
  }
}

// 测试:init参数自动推导为[string, number]
const strResource = new Resource("foo");
const numResource = new Resource(123);

new ResourceContainer1([strResource, numResource], (str, num) => {
  console.log(str.toUpperCase()); // str被推断为string
  console.log(num.toFixed(1)); // num被推断为number
});

结构2:构造函数接收包含dependencies和init的配置对象

逻辑和结构1一致,只是把参数包装在配置对象中:

class ResourceContainer2 {
  constructor<
    D extends Resource<any>[]
  >(config: {
    dependencies: [...D],
    init: (...args: { [K in keyof D]: D[K] extends Resource<infer T> ? T : never }) => void
  }) {
    const args = config.dependencies.map(dep => dep.getValue()) as { [K in keyof D]: D[K] extends Resource<infer T> ? T : never };
    config.init(...args);
  }
}

// 测试:init参数同样自动推导为[string, number]
new ResourceContainer2({
  dependencies: [strResource, numResource],
  init: (str, num) => {
    console.log(str.length); // str是string
    console.log(num + 456); // num是number
  }
});

关键要点

  • [...D]是核心:它告诉TypeScript不要把dependencies当成普通数组,而是作为元组处理,这样才能保留每个元素的具体类型信息,否则TS会将数组推断为Resource<unknown>[]之类的模糊类型。
  • 映射类型+infer:通过D[K] extends Resource<infer T> ? T : never从每个Resource实例中提取其泛型参数T,组成与dependencies顺序对应的参数元组。
  • 类型断言:Array.map()返回的是普通数组,需要断言为推导后的元组类型,确保调用init时类型完全匹配。

内容的提问来源于stack exchange,提问作者Harry Burns

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 02:45:27