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

TypeScript泛型无法从函数参数自动推断传入类型的问题咨询

问题描述
type Method = "get" | "post" | "put" | "patch" | "delete" | "head" | "options";

export interface TRoute<TMethod, TResponse = unknown, TParmas = undefined> {
  payload: {
    method: TMethod;
    url: string;
  };
}

export const route = <TResponse, TMethod extends Method = Method>(
  method: TMethod,
  url: string
): TRoute<TMethod, TResponse> => ({
  payload: { method, url },
});

const result = route<{ result: string[] }>("get", "/index")

实际类型推导结果

变量result的推导类型为:

const result: TRoute<Method, {
    result: string[];
}, undefined>

期望类型推导结果

const result: TRoute<"get", {
    result: string[];
}, undefined>

需求约束:不希望手动传入第二个泛型参数,需要TMethod的类型直接从传入的method实参中推断得到对应的字面量类型。


原因

TypeScript 目前不支持部分泛型参数推断:显式传入泛型列表中的部分参数时,剩余未手动传入的泛型不会再从函数实参推导,会直接使用预设的泛型默认值。
当前代码泛型顺序为<TResponse, TMethod extends Method = Method>,调用时手动传入了第一个泛型TResponse,未手动传入的TMethod直接命中默认值Method联合类型,不会从传入的"get"实参推断为字面量类型。

解决方案

用柯里化拆分泛型传入和实参传入的逻辑:外层函数接收需要手动指定的TResponse泛型,内层函数接收实际参数、自动推断TMethod类型,完全满足需求,修改后代码如下:

type Method = "get" | "post" | "put" | "patch" | "delete" | "head" | "options";

export interface TRoute<TMethod, TResponse = unknown, TParmas = undefined> {
  payload: {
    method: TMethod;
    url: string;
  };
}

export const route = <TResponse = unknown>() => <TMethod extends Method>(
  method: TMethod,
  url: string
): TRoute<TMethod, TResponse> => ({
  payload: { method, url },
});

// 调用时外层传入响应类型,内层传入接口参数,TMethod自动推断为"get"
const result = route<{ result: string[] }>()("get", "/index")

此时result的推导类型完全符合预期:TRoute<"get", { result: string[] }, undefined>。

注:TypeScript 官方正在迭代部分泛型参数推断特性,特性正式上线后可无需修改调用写法直接实现需求,当前版本(5.x及以下)柯里化是兼容性最高的实现方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 02:48:37