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

泛型类类型推断困境:如何同时实现参数与返回类型推导?

问题描述

尝试在TypeScript泛型类中同时实现以下两个目标:

  • 回调函数cb的参数能访问对应id的字符串字面量类型
  • 调用get方法时能正确推断对应cb的返回类型

现有两种实现均存在缺陷:

  • 第一种实现可正确推断get方法的返回类型,但cb的参数无法获取id的具体字面量类型,仅能识别为{ [x: string]: any }
  • 第二种实现让cb参数能拿到id的字面量类型,但get方法的返回类型退化为any
解决方案

通过优化泛型定义,将每个对象的id与cb参数类型强关联,同时让类的泛型保留数组中每个元素的具体字面量类型,即可同时满足两个需求。

完整实现代码

type MyObj<T extends string> = {
  id: T;
  cb: (p?: { [K in T]: any }) => unknown;
}

class MyClass<const T extends MyObj<string>[]> {
  constructor(p: T) {}

  get<K extends T[number]["id"]>(p: K): 
    ReturnType<Extract<T[number], { id: K }>["cb"]> {
    return null as any;
  }
}

// 验证示例
const my = new MyClass([
  {
    id: "foo",
    cb: (p) => {
      // p 的类型为 { foo?: any },可正确识别字面量 foo
      return "foo";
    }
  },
  {
    id: "bar",
    cb: (p) => {
      // p 的类型为 { bar?: any }
      return 1;
    }
  }
]);

const r1 = my.get("foo"); // 类型推断为 string
const r2 = my.get("bar"); // 类型推断为 number

核心要点

  • MyObj<T>中,cb的参数类型{ [K in T]: any }会根据T(即id的字符串字面量)生成专属的键类型,确保每个cb的参数仅对应自身的id
  • 类的泛型const T extends MyObj<string>[]使用const断言,强制TypeScript保留数组中每个元素的字面量细节,避免类型自动拓宽
  • get方法通过Extract<T[number], { id: K }>精准筛选出对应id的对象类型,从而正确提取并推断cb的返回类型

内容的提问来源于stack exchange,提问作者Flo Ragossnig

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 09:15:12