我正在玩TypeScript,我有一些功能混合,Eventable而且Settable我想混合到一个Model类(假装它像Backbone.js模型):
function asSettable() {
this.get = function(key: string) {
return this[key];
};
this.set = function(key: string, value) {
this[key] = value;
return this;
};
}
function asEventable() {
this.on = function(name: string, callback) {
this._events = this._events || {};
this._events[name] = callback;
};
this.trigger = function(name: string) {
this._events[name].call(this);
}
}
class Model {
constructor (properties = {}) {
};
}
asSettable.call(Model.prototype);
asEventable.call(Model.prototype);
Run Code Online (Sandbox Code Playgroud)
上面的代码工作正常,但如果我尝试使用其中一个混合方法,则无法编译(new Model()).set('foo', 'bar').
我可以解决这个问题
interfacemixins的声明get/ set/ on/ trigger在方法Model声明虚拟声明周围有一个干净的方法吗?
Ste*_*man 12
这是使用interfaces和static create()方法处理mixins的一种方法.接口支持多重继承,因此可以防止你必须重新定义interfaces你的mixins,并且该static create()方法负责给你一个实例Model()作为一个IModel(<any>需要强制转换编译器警告.)你需要复制所有的为您的成员定义Model上IModel它吮吸,但它似乎是最干净的方式来实现你的打字稿的当前版本想要什么.
编辑:我已经确定了一种稍微简单的方法来支持mixins,甚至创建了一个帮助类来定义它们.细节可以在这里找到.
function asSettable() {
this.get = function(key: string) {
return this[key];
};
this.set = function(key: string, value) {
this[key] = value;
return this;
};
}
function asEventable() {
this.on = function(name: string, callback) {
this._events = this._events || {};
this._events[name] = callback;
};
this.trigger = function(name: string) {
this._events[name].call(this);
}
}
class Model {
constructor (properties = {}) {
};
static create(): IModel {
return <any>new Model();
}
}
asSettable.call(Model.prototype);
asEventable.call(Model.prototype);
interface ISettable {
get(key: string);
set(key: string, value);
}
interface IEvents {
on(name: string, callback);
trigger(name: string);
}
interface IModel extends ISettable, IEvents {
}
var x = Model.create();
x.set('foo', 'bar');
Run Code Online (Sandbox Code Playgroud)
几年前,Typescript 中内置了一种新方法,称为“mixin 类”。文档中没有很好地介绍它,但他们确实有一个注释良好的示例来很好地描述该模式。适用于您的情况,它可能看起来像:
type Constructor = new (...args: any[]) => {}
function Settable<TBase extends Constructor>(Base: TBase) {
return class extends Base {
_props: Record<string, any> = {};
get(key: string) {
return this._props[key];
}
set(key: string, value: any) {
this._props[key] = value;
return this;
}
}
}
function Eventable<TBase extends Constructor>(Base: TBase) {
return class extends Base {
_events: Record<string, () => void> = {};
on(name: string, callback: () => void) {
this._events[name] = callback;
}
trigger(name: string) {
this._events[name].call(this);
}
}
}
class Model extends Settable(Eventable(Object)) {
constructor(properties = {}) {
super();
}
}
Run Code Online (Sandbox Code Playgroud)
这将为您提供所需的打字功能,以便您能够在通话时(new Model()).set('boo', 'bar')获得完整的打字支持。没有虚拟声明。
| 归档时间: |
|
| 查看次数: |
8751 次 |
| 最近记录: |