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

TypeScript调用泛型函数时保留类型参数的实现方案

实现支持动态泛型参数的带Modifier函数

原有代码背景

先看基础的类型定义与包装函数:

type GenericFunc<T> = () => Promise<T>

interface FuncWithModifier<T> extends GenericFunc<T> {
  modifier: GenericFunc<T>
}

const wrapFunction = <T> (func: GenericFunc<T>): FuncWithModifier<T> => {
    const modifier: GenericFunc<T> = async () => func()
    return Object.assign(func, { modifier })
}

这段代码可以创建绑定固定类型T的带modifier的函数,但无法实现调用时动态指定泛型参数的需求。

需求目标

我们需要创建一个泛型函数,支持以下调用方式:

const unknown1: unknown = await genericFunc()
const unknown2: unknown = await genericFunc.modifier()
const num1: number = await genericFunc<number>()
const num2: number = await genericFunc.modifier<number>()
const bool1: boolean = await genericFunc<boolean>()
const bool2: boolean = await genericFunc.modifier<boolean>()

即主函数和modifier都能在调用时动态指定返回值类型,而非绑定固定的T。

解决方案

核心思路是:将GenericFunc定义为自身支持泛型参数的函数类型,而非依赖外部绑定的T。调整后的代码如下:

1. 重新定义类型

// 定义自身可接收泛型参数的函数类型,默认类型为unknown
type GenericFunc = <T = unknown>() => Promise<T>;

// 带modifier的函数类型,modifier同样是可动态指定泛型的函数
interface FuncWithModifier extends GenericFunc {
  modifier: GenericFunc;
}

2. 调整包装函数实现

const wrapFunction = (func: () => Promise<any>): FuncWithModifier => {
  // modifier作为泛型函数,调用时将结果断言为指定的T
  const modifier: GenericFunc = async <T = unknown>() => func() as Promise<T>;
  // 主函数同理,支持动态指定返回类型
  const wrappedFunc: GenericFunc = async <T = unknown>() => func() as Promise<T>;
  
  // 为函数添加modifier属性并返回
  return Object.assign(wrappedFunc, { modifier });
};

3. 创建目标泛型函数

const genericFunc = wrapFunction(async () => null as any);

验证调用

此时即可按照需求调用:

const unknown1: unknown = await genericFunc();
const unknown2: unknown = await genericFunc.modifier();
const num1: number = await genericFunc<number>();
const num2: number = await genericFunc.modifier<number>();
const bool1: boolean = await genericFunc<boolean>();
const bool2: boolean = await genericFunc.modifier<boolean>();

原理说明

原有代码的问题在于FuncWithModifier<T>将泛型T绑定到了整个接口上,导致每个实例只能对应一个固定类型。调整后,我们让主函数和modifier本身成为独立的泛型函数,允许在调用时动态传入类型参数,从而实现了灵活的类型指定能力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 19:50:29