我有TypeScript ES6 Class,假设它看起来像这样
class Classic
private _member: Object;
constructor(member: Object) {
this._member = member;
}
}
我有一些富有的对象,它包含很多方法,我想继承,但该对象不是TS或ES6类,它只是POJO(ObjectLiteral)。
所以我做了快速而又脏的继承,比如
Object.assign(Classic.prototype, ObjectLiteralWithMethods);
无需深层复制,一切正常。
如何告诉TypeScript Classic
具有这些继承的方法并指定其行为?
我搜索了诸如声明或定义AND类AND方法之类的关键字,但我的google-fu还不够。
我尝试为Classic
定义界面,但它也不起作用。
我试图声明类似
declare class ObjectLiteralWithMethods {
public method(): void;
protected _method(parameter: string): void;
}
然后将该声明扩展为
class Classic extends ObjectLiteralWithMethods { ... }
但是然后TypeScript要我在super()
中调用constructor
,但失败了。
我知道我可以在Classic
上实现“虚拟”方法,如
class Classic {
dummyMethodImplementation(param: string): string {
return param;
}
}
但这将是痛苦和低效的。我只想定义/声明类Classic
已扩展。
排序......
我的案例中的ObjectLiteralWithMethods
实际上是jQuery小部件的原型。所以,我扩展了原型的所有者。
它需要一些补丁,因为TS不知道所有者所以我做了:
// declaring the properties and methods which will be inherited by my class
declare class JQueryUIWidget {
public property: string;
public method(): string;
...
}
// must declare a constructor for JQueryUIWidget to be able to extend
// and cast the value to any, so TS do not mind
const Widget: { new (): JQueryUIWidget } = $.Widget as any;
// and then extend that declaration
class Classic extends Widget {
constructor() {
super(); // super(); is mandatory here, with plain object it
// did not worked, but since Widget is in fact a Function
// it works now
}
}
答案 0 :(得分:0)
你可以这样做:
declare class ObjectLiteralWithMethods {
public method(): void;
public _method(parameter: string): void;
}
class Classic implements ObjectLiteralWithMethods {
private _member: Object;
constructor(member: Object) {
this._member = member;
}
method: () => void;
_method: (parameter: string) => void;
}
但您无法在ObjectLiteralWithMethods
中使用受保护的成员/方法,因为您将其用作界面。
如果您需要覆盖子类中Classic
中的方法,那么您需要使用stabs来实现这些方法:
class Classic implements ObjectLiteralWithMethods {
private _member: Object;
constructor(member: Object) {
this._member = member;
}
method() {};
_method(parameter: string) {}
}
class Other extends Classic {
method() {
}
}
Classic
中的方法为空,您可以使用ObjectLiteralWithMethods中的实现覆盖它们。
答案 1 :(得分:0)
有点晚了,但是当将遗留系统的一部分转换为TypeScript时,我有一个类似的要求,因此这可能对其他人有所帮助。
如果您知道您的类将在运行时使用其他方法进行增强,并且您只想为这些方法提供类型信息和智能感知,并且您不想编写难看的存根,则可以尝试以下操作:
首先,定义详细描述运行时方法的接口:
interface RuntimeImplementedType {
public method(): void;
}
interface AnotherRuntimeImplementedType {
public other_method(): void;
}
然后定义一个变量,将其类型指定为构造函数,以返回要通知TypeScript您的类在运行时实现的类型的并集。为变量分配一个函数,该函数返回一个空对象文字,并将其转换为“ any”,以避免编译器抱怨,并确保在编译时实际上扩展的对象只是一个普通的旧空对象。
const Base: new() => RuntimeImplementedType & AnotherRuntimeImplementedType = (() => {}) as any;
现在定义新类,从构造函数的变量开始扩展:
class Classic extends Base {
public doSomething() {
this.method();
this.other_method();
}
}
接口中的所有方法都应该可用,但不必实际提供实现。