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

TypeScript中组合重载函数时如何实现正确的类型推导?

解决TypeScript重载函数通过高阶函数传递后的类型推导问题

问题出在你定义的apply函数上:原apply用(arg: T) => R来约束传入的函数,TypeScript遇到重载函数时,会自动把所有重载签名合并成单一的宽泛签名——参数取所有重载参数的联合类型,返回值取所有返回值的联合类型。所以apply(asDate)得到的函数类型会变成(val: unknown) => Date | null,调用时自然只能推导出Date | null。

解决办法:让apply保留原函数的重载签名

修改apply的泛型定义,直接让它返回传入函数的原始类型,而不是强行转换成单签名函数:

/** parses as `Date` instance */
export function asDate(val: string | number | Date): Date;
export function asDate(val: string | number | Date | null | undefined): Date | null;
export function asDate(val: unknown) {
  return val instanceof Date ? val : typeof val === 'number' || typeof val === 'string' ? new Date(val) : null;
}

// 修改后的apply,保留原函数的完整类型(包括重载)
export function apply<T extends (...args: unknown[]) => unknown>(fn: T): T {
  return fn;
}

const date0 = asDate(123); // 类型:Date
const date1 = apply(asDate)(123); // 类型:Date(符合预期)
const date2 = apply(asDate)(null); // 类型:Date | null(正确匹配重载)

原理说明

当apply的泛型T被推断为asDate的完整重载类型时,返回T会直接保留所有重载签名。此时调用apply(asDate)(123),TypeScript会像直接调用asDate(123)一样,匹配对应的重载签名,正确推导出返回类型为Date。

如果需要更宽松的参数约束,也可以把unknown[]换成any[],效果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 07:55:08