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

TypeScript泛型函数如何自动推导类型,无需显式传入?

解决TypeScript分组计数函数的泛型自动推导问题

问题背景

需要实现一个按指定键对数组元素分组计数的函数,当前代码功能正常,但调用时必须显式指定泛型类型,无法通过传入参数自动推导泛型,导致使用不便。

问题原因

原函数的泛型参数顺序和约束逻辑存在问题:

  • 泛型参数FilterOptions被放在最后,而它实际上是T[PropName]的类型,TypeScript无法从已推导的T和PropName反向推导FilterOptions;
  • T的约束写法<T extends { [R in PropName]: FilterOptions }>逻辑倒置,应该是从T和PropName确定值类型,而非先定义值类型再约束T。

解决方案

调整泛型参数结构,直接从T和PropName推导目标属性的值类型,无需单独定义FilterOptions泛型参数。具体修改如下:

修改后的函数代码

export const aggregateProp = <T, PropName extends keyof T>(
  evaluations: T[],
  propName: PropName
) => {
  type FilterOptions = T[PropName];
  const totalsByResult = evaluations.reduce((acc, { [propName]: result }) => {
    acc.set(result, (acc.get(result) ?? 0) + 1);
    return acc;
  }, new Map<FilterOptions | 'ALL', number>());
  totalsByResult.set('ALL', evaluations.length);
  return totalsByResult;
};

调用验证

使用原有的Evaluation接口和测试数组,现在可以直接隐式调用,TypeScript会自动推导泛型类型:

interface Evaluation {
  propA: string;
  result: FilterOptions;
  probC: boolean;
}

type FilterOptions = 'FAILED' | 'SUCCESS' | 'SKIPPED' | 'ALL';

const evaluations: Evaluation[] = [
  { propA: 'a', result: 'FAILED', probC: true },
  { propA: 'b', result: 'FAILED', probC: false },
  { propA: 'c', result: 'SUCCESS', probC: true },
  { propA: 'd', result: 'SKIPPED', probC: false },
  { propA: 'e', result: 'SKIPPED', probC: true },
  { propA: 'f', result: 'FAILED', probC: false },
];

// 自动推导为 Map<FilterOptions | 'ALL', number>
const implicit = aggregateProp(evaluations, 'result');

说明

  • 通过type FilterOptions = T[PropName]从已推导的T和PropName获取目标属性的类型,避免了单独定义泛型参数的麻烦;
  • 泛型参数简化为<T, PropName extends keyof T>,TypeScript可以轻松从传入的数组和属性名参数自动推导这两个类型,进而确定FilterOptions的类型;
  • 返回的Map类型明确为FilterOptions | 'ALL',既保留了原有的分组计数,也包含了总数量的'ALL'键。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:47:09