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

如何实现TypeScript返回函数的多参数支持与自动类型推导?

解决TypeScript中函数返回值的类型推断问题

问题描述

我需要实现一个outer函数,它接收string类型参数,返回一个使用该参数的函数。返回的函数支持两种参数类型:

  • 接收string时,返回{ arg: string }类型的对象
  • 接收string[]时,返回该对象组成的数组
    希望TypeScript能自动识别返回函数的参数与对应返回类型,无需每次使用时断言。

我尝试的代码如下:

function outer<T extends { arg: string }>(arg: string): (id: string) => T;
function outer<T extends { arg: string }>(arg: string): (id: string[]) => T[];
function outer<T extends { arg: string }, S extends string | string[]>(arg: string): S extends string ? (id: string) => T : (id: string[]) => T[];

function outer<T extends { arg: string }>(arg: string): (id: string | string[]) => T | T[] {
  return (id: string | string[]) => {
    if (Array.isArray(id)) {
      return [{ arg }] as T[];
    }

    return { arg } as T;
  }
}

type ArgType = { arg: string };

const result = outer<ArgType>('arg')(['id']);

执行时遇到错误:

Argument of type 'string[]' is not assignable to parameter of type 'string'.

问题原因

当前的重载写法存在逻辑问题:第三个重载使用了泛型S,但调用outer时并没有显式指定S的类型,TypeScript无法自动推断S,因此会优先匹配第一个重载(接收string参数的版本),导致传入数组时报错。

解决方案

我们可以通过两种方式修复这个问题,让TypeScript能正确推断返回函数的参数与返回类型:

方式一:为返回的函数定义重载

function outer<T extends { arg: string }>(arg: string): {
  (id: string): T;
  (id: string[]): T[];
} {
  return ((id: string | string[]) => {
    if (Array.isArray(id)) {
      return [{ arg }] as T[];
    }
    return { arg } as T;
  }) as any;
}

type ArgType = { arg: string };

// 自动推断result为ArgType[]
const result = outer<ArgType>('arg')(['id']);
// 自动推断singleResult为ArgType
const singleResult = outer<ArgType>('arg')('id');

方式二:使用泛型条件类型

function outer<T extends { arg: string }>(arg: string) {
  return <S extends string | string[]>(id: S): S extends string ? T : T[] => {
    if (Array.isArray(id)) {
      return [{ arg }] as T[];
    }
    return { arg } as T;
  }
}

type ArgType = { arg: string };

// 自动推断result为ArgType[]
const result = outer<ArgType>('arg')(['id']);
// 自动推断singleResult为ArgType
const singleResult = outer<ArgType>('arg')('id');

说明

  • 方式一通过为返回的函数直接定义重载,明确告知TypeScript该函数支持的参数类型和对应返回值类型,TypeScript能准确匹配重载并完成类型推断。
  • 方式二将泛型S转移到返回的函数上,调用返回函数时,TypeScript会根据传入的id类型自动推断S,再通过条件类型确定最终返回值类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 12:12:34