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

为何签名中的泛型会破坏TypeScript类型推断?

问题解决:保留泛型默认值时修复TypeScript类型推断失效

问题背景

移除xx函数的泛型定义后,TypeScript类型推断正常;但保留xx<T>泛型且resource函数的R默认值为null时,类型推断失效。原代码如下:

declare function resource<T, R = null>(options: ResourceOptions<T, R>): R;

interface ResourceOptions<T, R> {
  params?: () => R;
  loader: (param: R) => T;
}

function xx<T>(source: T): () => T {
  return () => source;
}

const res = resource({
  params: xx(""),
  loader: (params) => params,
});

核心原因

原resource函数的泛型参数顺序是T在前、R在后。TypeScript会优先推断靠前的泛型参数,而T的推断依赖loader的参数类型(即R),但R有默认值null,导致TypeScript直接将R设为null,进而与params返回的string类型冲突,推断失败。

解决方案

方案1:调整泛型参数顺序(推荐)

将R放在T前面,让TypeScript先从params推断R的类型,再基于R推断T:

declare function resource<R = null, T>(options: ResourceOptions<T, R>): R;

interface ResourceOptions<T, R> {
  params?: () => R;
  loader: (param: R) => T;
}

function xx<T>(source: T): () => T {
  return () => source;
}

const res = resource({
  params: xx(""),
  loader: (params) => params,
});
// res 的类型被正确推断为 string

方案2:显式指定部分泛型参数

如果不想调整泛型顺序,可以在调用resource时显式指定R的类型,让T自动推断:

const res = resource<string, string>({
  params: xx(""),
  loader: (params) => params,
});

方案3:优化接口类型关联

通过修改ResourceOptions,让loader的参数类型与params的返回值类型强关联,无需依赖泛型顺序:

declare function resource<T, R = null>(options: ResourceOptions<T, R>): R;

interface ResourceOptions<T, R> {
  params?: () => R;
  loader: (param: NonNullable<R>) => T;
}

// 调用时通过类型断言辅助推断
const res = resource({
  params: xx("") as () => string,
  loader: (params) => params,
});

说明

方案1是最简洁自动的解决方式,完全利用TypeScript的泛型推断优先级规则,无需额外手动指定类型,同时保留了R=null的默认值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 16:37:27