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

如何在Typescript中编写支持接收抽象类参数的类装饰器

解决方案

前提说明

TypeScript 4.2及以上版本正式支持抽象构造签名的类型定义,你之前遇到的语法报错要么是TS版本低于4.2,要么是错误地将abstract修饰符用在了interface的成员上(TS目前不支持接口内部声明抽象构造签名,仅类型别名支持该写法)。

通用实现方案

通过函数重载分别处理普通类和抽象类的传入场景,同时保留完整的类型提示:

// 普通构造函数类型
type Constructor<T = unknown, TArgs extends any[] = any[]> = new (...args: TArgs) => T;
// 抽象构造函数类型,TS 4.2+ 支持
type AbstractConstructor<T = unknown, TArgs extends any[] = any[]> = abstract new (...args: TArgs) => T;

// 重载1:接收普通类,返回带新增属性的普通类
export function myDecorator<T extends Constructor>(Target: T): T & Constructor<InstanceType<T> & {
  prop: string;
  fn(arg: string): void;
}>;
// 重载2:接收抽象类,返回带新增属性的抽象类
export function myDecorator<T extends AbstractConstructor>(Target: T): T & AbstractConstructor<InstanceType<T> & {
  prop: string;
  fn(arg: string): void;
}>;

export function myDecorator(Target: AbstractConstructor) {
  // 若不需要在装饰器内实现传入抽象类的抽象方法,可给返回类加abstract修饰,交给后续子类实现
  const MyDecoratedClass = class extends Target {
    prop!: string;
    fn(arg: string) {
      console.log(this.prop);
    }
  };

  const name = `Decorated${Target.name}`;
  Object.defineProperty(MyDecoratedClass, 'name', { value: name });

  return MyDecoratedClass;
}

调整后即可直接传入抽象类使用,无需额外的中间层基类:

abstract class SomeAbstractClass {
  abstract test(): void;
}

// 正常使用,无类型报错
class MyImplementedClass extends myDecorator(SomeAbstractClass)<string> {
  foo: string = '';
  // 实现抽象方法
  test() {
    console.log('test');
  }
}

低版本TS兼容方案

如果无法升级TS到4.2以上,可以通过类型断言绕开类型检查,仅能保证运行正常,会丢失部分抽象类的类型校验:

type Class<T, TArgs extends any[] = any[]> = new(...args: TArgs) => T;

export function myDecorator<T extends Class<any>>(Target: T) {
  // 传入抽象类时用as any绕开构造函数类型校验
  const MyDecoratedClass = class extends (Target as any) {
    prop!: string;
    fn(arg: string) {
      console.log(this.prop);
    }
  };

  const name = `Decorated${Target.name}`;
  Object.defineProperty(MyDecoratedClass, 'name', { value: name });

  return MyDecoratedClass as typeof MyDecoratedClass & T;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 07:51:02