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

如何在TypeScript类中包装泛型函数并保留其泛型特性?

在类中包装泛型函数并保留泛型特性

我需要在类中包装泛型函数,同时保留原函数的泛型特性,但尝试了两种写法都未能实现目标:

第一种尝试:泛型完全丢失

const func = <G extends string>(p: G) => p;

class Func<A extends any[], R> {
  constructor(private readonly func: (...args: A) => R) {}

  public call(...args: A): R {
    return this.func(...args);
  }

  public catch(cb: (error: unknown) => void) {}

  // 更多方法...
}

实例化后泛型信息完全丢失:

const use = new Func(func); // 类型推导为 Func<[p: any], any>

第二种尝试:实例类型保留,但调用时泛型丢失

class Func<F extends (...args: A) => R, A extends any[], R> {
  constructor(private readonly func: F) {}

  public call(...args: A): R {
    return this.func(...args);
  }

  public catch(cb: (error: unknown) => void) {}
}

虽然实例的类型能正确关联原函数,但调用call方法时,返回类型依然是any:

use.call('str'); // 返回类型为 any

需求总结

需要一种实现方式,让类既能包装泛型函数,又能让类的方法(如call)完全保留原函数的泛型特性,欢迎任何创造性的解法。

可行解决方案

方案1:让call方法继承原函数的泛型参数

通过TypeScript的类型工具提取原函数的参数和返回类型,让call方法复用这些类型信息:

const func = <G extends string>(p: G) => p;

class Func<F extends (...args: any[]) => any> {
  constructor(private readonly func: F) {}

  public call<T extends Parameters<F>[0]>(...args: Parameters<F>): ReturnType<F> {
    return this.func(...args) as ReturnType<F>;
  }

  public catch(cb: (error: unknown) => void) {}
}

const use = new Func(func);
const result = use.call('str'); // result 类型为 "str",泛型特性保留

方案2:利用infer自动推导原函数类型

通过条件类型中的infer关键字,自动提取原函数的参数和返回类型,确保call方法的类型与原函数完全一致:

const func = <G extends string>(p: G) => p;

class Func<F> {
  constructor(private readonly func: F) {}

  public call(...args: F extends (...args: infer A) => any ? A : never): 
    F extends (...args: any[]) => infer R ? R : never {
    return this.func(...args as any);
  }

  public catch(cb: (error: unknown) => void) {}
}

const use = new Func(func);
const result = use.call('str'); // result 类型为 "str"

方案3:直接复用原函数作为类方法

将原函数直接赋值给类的call方法,完全保留原函数的泛型签名,这是最直接的实现方式:

const func = <G extends string>(p: G) => p;

class Func<F extends (...args: any[]) => any> {
  public call: F;

  constructor(func: F) {
    this.call = func;
  }

  public catch(cb: (error: unknown) => void) {}
}

const use = new Func(func);
const result = use.call('str'); // result 类型为 "str"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 04:47:20