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

如何编写泛型函数,根据泛型参数返回不同结构的值?

如何实现根据泛型返回不同值的TypeScript函数

当然可以做到!要实现你想要的这个泛型函数,我们可以借助TypeScript的泛型条件类型或者函数重载,让函数根据传入的泛型参数返回对应结构的值,同时保证类型完全匹配你的需求。

先回顾你的需求:

type FooType = T | T[];
let baz: FooType<Object[]> = Foo<Object[]>('bar') // 返回值:[{bar: 'bar'}];
let bazbar: FooType = Foo('bar') // 返回值:{ bar: 'bar' }

方法一:使用泛型条件类型

这种方式能让函数的返回类型根据泛型参数自动推导,逻辑更紧凑:

// 保留你定义的FooType,也可以根据需求让返回类型更精准
type FooType<T> = T | T[];

// 泛型函数,通过条件类型动态确定返回类型
function Foo<T>(str: string): T extends Array<any> ? T : T {
  // 借助类型断言和数组判断辅助编译时类型推导
  if (Array.isArray([] as T)) {
    return [{ [str]: str }] as T;
  } else {
    return { [str]: str } as T;
  }
}

// 测试你的示例
let baz: FooType<Object[]> = Foo<Object[]>('bar'); // 返回 [{bar: 'bar'}]
let bazbar: FooType<Object> = Foo<Object>('bar'); // 返回 {bar: 'bar'}

核心逻辑是T extends Array<any> ? T : T这个条件类型:编译时会检查泛型T是否为数组类型,是则返回数组结构,否则返回单个对象结构。

方法二:使用函数重载

如果想要更直观的类型签名,用函数重载分别定义两种场景的输入输出会更清晰:

type FooType<T> = T | T[];

// 重载签名1:泛型为数组类型时,返回对应数组
function Foo<T extends any[]>(str: string): T;
// 重载签名2:泛型为非数组类型时,返回单个对象
function Foo<T>(str: string): T;

// 函数实现(返回类型需兼容所有重载场景)
function Foo(str: string): any {
  // 根据调用时的泛型预期构造结果
  return Array.isArray([] as any) ? [{ [str]: str }] : { [str]: str };
}

// 测试示例
let baz: FooType<Object[]> = Foo<Object[]>('bar'); // 返回 [{bar: 'bar'}]
let bazbar: FooType<Object> = Foo<Object>('bar'); // 返回 {bar: 'bar'}

函数重载的优势在于类型提示更明确,调用时TypeScript会自动匹配对应的重载规则,给出精准的类型校验。

补充说明

由于JavaScript运行时不存在泛型概念,我们无法直接获取泛型T的运行时类型。代码中的Array.isArray([] as T)更多是辅助TypeScript完成编译时的类型推导,实际运行时不会依赖这个判断(因为调用时泛型已经确定了返回类型)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:10:00