我想出了以下使用泛型和ES5 getters/setters,构建了/u/blorkfish答案。
class TypedModel<t> extends Backbone.Model {
constructor(attributes?: t, options?: any) {
super(attributes, options);
var defaults = this.defaults();
for (var key in defaults) {
var value = defaults[key];
((k: any) => {
Object.defineProperty(this, k, {
get:(): typeof value => {
return this.get(k);
},
set: (value: any) => {
this.set(k, value);
},
enumerable: true,
configurable: true
});
})(key);
}
}
public defaults(): t {
throw new Error('You must implement this');
return <t>{};
}
}
注:Backbone.Model默认值是可选的,但由于我们用它来构建getter和setter,现在是强制性的。抛出的错误迫使你这样做。也许我们可以想一个更好的方法?
,并使用它:
interface IFoo {
name: string;
bar?: number;
}
class FooModel extends TypedModel<IFoo> implements IFoo {
public name: string;
public bar: number;
public defaults(): IFoo {
return {
name: null,
bar: null
};
}
}
var m = new FooModel();
m.name = 'Chris';
m.get('name'); // Chris
m.set({name: 'Ben', bar: 12});
m.bar; // 12
m.name; // Ben
var m2 = new FooModel({name: 'Calvin'});
m2.name; // Calvin
这是理想的稍微详细,它要求你使用默认值,但它工作得很好。
没有答案,但我发现了同样的问题,并用一组不同的工具来管理数据和绑定(普通但强类型的TS对象+ Linq。 js + jsrender/jsviews(带有可观察类 - http://bit.ly/WyNbhn))。参考:http://linqjs.codeplex.com/ https://github.com/BorisMoore – JcFx 2013-03-08 16:10:02
我想你可能需要等待TypeScript支持泛型以一种理智的方式做到这一点(v0。9) – 2013-03-08 17:29:31
@RyanCavanaugh现在的答案是不被接受的,因为像数组这样更复杂的对象会崩溃,现在TypeScript支持泛型,也许你可以提供一个更新的答案? – parliament 2013-08-21 21:03:54