是否可以使用类型定义重载整个类?
例如,有两个类不同,只是如果其中一个具有泛型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>
的构造函数。
答案 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])
}
}