typescript类重载

时间:2018-03-30 19:31:38

标签: typescript generics overloading

是否可以使用类型定义重载整个类?

例如,有两个类不同,只是如果其中一个具有泛型typedef,它也应该在构造函数参数中接受它。如果没有,则不需要该param和自定义构造函数。

export abstract class MyClass implements OtherClass {
  readonly foo;

  static get bar(): string {
    return "bar";
  }
}

export abstract class MyPayloadClass<T> extends MyClass {
  constructor(public readonly payload: T) {
    super();
  }
}

目标是将这两者合并在一起。因此,我们只有一个MyClass,并且只有在提供类型payload的情况下,它才会选择包含<T>的构造函数。

2 个答案:

答案 0 :(得分:1)

虽然两个类都没有单一的实现,但两者都可以有一个构造函数,实际上有一种创建泛型或非泛型版本的统一方法。

我们所做的是声明一个变量,该变量将保存类构造函数的有效负载版本,并使用非有效负载版本重载构造函数。运行时实现将始终是有效负载版本,但如果没有有效负载,则会对非有效负载版本进行类型检查。

export abstract class MyClass  {
  readonly foo;

  static get bar(): string {
    return "bar";
  }
}

export abstract class MyPayloadClass<T> extends MyClass {
  constructor(public readonly payload: T) {
    super();
  }
}



const Both: typeof MyPayloadClass & { new() : MyClass } = MyPayloadClass as any;

let a = new Both();
let b = new Both(1);

b.payload // ok
a.payload // error

Both.bar // statics work

答案 1 :(得分:0)

您可以使用默认泛型,但它需要始终将参数传递给构造函数,即使它只是undefined

export class MyPayloadClass<T = void> extends MyClass {
  constructor(public readonly payload: T) {
    super();
  }
}


const c = new MyPayloadClass() // doesn't work
const c2 = new MyPayloadClass(undefined)

或者,您可以使用类型重载创建静态工厂方法...

export class MyPayloadClass<T> extends MyClass {
  constructor(public readonly payload: T) {
    super();
  }

  public static factory(): MyPayloadClass<void>
  public static factory<T>(payload: T): MyPayloadClass<T>
  public static factory(payload?: any) {
    return new MyPayloadClass(payload)
  }
}

但这不适用于抽象类。使用reflect api来解决这个问题。

export abstract class MyPayloadClass<T> extends MyClass {
  constructor(public readonly payload: T) {
    super();
  }

  public static factory(): MyPayloadClass<void>
  public static factory<T>(payload: T): MyPayloadClass<T>
  public static factory(payload?: any) {
    return Reflect.construct(this, [payload])
  }
}