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

TypeScript如何依据入参是否为undefined动态设置泛型函数返回类型

你的实现失效的核心原因是TypeScript无法自动根据valueKey是否传入来缩小泛型的条件返回类型,默认会返回两种类型的联合,因此出现赋值报错。

采用函数重载可以完美匹配你的预期需求,实现代码如下:

export interface ToObject<T> {
  [k: string]: T;
}

// 重载1:未传入valueKey时,返回值为对象映射,值类型为原数组项类型
export function toObject<T>(list: T[], key: keyof T): ToObject<T>;
// 重载2:传入valueKey时,返回值为对象映射,值类型为对应valueKey的属性类型
export function toObject<T, V extends keyof T>(list: T[], key: keyof T, valueKey: V): ToObject<T[V]>;

// 函数实现
export function toObject<T, V extends keyof T>(list: T[], key: keyof T, valueKey?: V) {
  return valueKey === undefined
    ? list.reduce((all, cur) => ({
        ...all,
        [cur[key] as unknown as string]: cur
      }), {} as ToObject<T>)
    : list.reduce((all, cur) => ({
        ...all,
        [cur[key] as unknown as string]: cur[valueKey]
      }), {} as ToObject<T[V]>);
}

效果验证

interface Data{
  a: string;
  b: string;
  c: string;
}
const list: Data[] = [
  {a:'a', b: 'b', c: 'c'},
  {a:'1', b: '2', c: '3'}
];

// 用法1 无报错,类型自动推导为ToObject<Data>
const dataMap: ToObject<Data> = toObject(list, 'a');

// 用法2 无报错,类型自动推导为ToObject<string>
const dataKeyMap: ToObject<string> = toObject(list, 'a', 'b');

函数重载的优势在于可以让TypeScript直接根据入参的数量、类型匹配对应的返回类型规则,不需要依赖条件类型的自动推导,避免了泛型默认值带来的联合类型歧义问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 20:45:05