如何将 Javascript "partial classes" 与 TypeScript 样式 class 定义一起使用
How can I use Javascript "partial classes" with TypeScript style class definition
我的应用程序有一个 api 包装器 class 最初是通过在 TypeScript 中输入它创建的,copying/pasting javascript 到我的应用程序中。
所以 class def 看起来像这样:
var SiteApi = (function () {
function SiteApi(initially)
{
//stuff
}
SiteApi.prototype.method1 = function(){/*stuff*/};
SiteApi.prototype.method2 = function(){/*stuff*/};
return SiteApi;
})();
现在,当它们位于管理页面时,我想添加一个额外的 admin.js 文件,其中将包含管理方法。例如
SiteApi.prototype.Admin.method1 = function(){/*stuff*/};
我找到了一个可以实现我想要的 "end result" 的示例:
// file main
function SomeObject() {
for (var i = 0, ii = SomeObject.Partial.length; i < ii; i++) {
SomeObject.Partial[i].apply(this, arguments);
}
}
SomeObject.Partial.SomeName = function() {
...
}
// file extra
SomeObject.Partial.SomeOtherName = function() {
...
}
(来自:Is it possible to give javascript partial class behavior like C# or monkey patching like Ruby does?)
但是,他们使用的 class 定义类型不同。
如何在保持 TypeScript 风格 class 定义的同时做一些类似于此示例的操作来添加管理功能?
作为参考,我们这样使用 class:
siteApi = new SiteApi();
所以我想还需要一行代码将管理功能绑定到其中。
注意,我可以使用 SiteApi.admin_method1
之类的东西,但问题是使用 TypeScript 样式 classes 原型是在定义中定义的,对象是执行的,所以它不会以后如何添加更多原型似乎很简单。
选项 1
扩展 SiteApi
但隐藏原始内容,例如您之后加载的 admin.js 会包含类似
的内容
SiteApi = (function (old_SiteApi) {
function SiteApi() {
old_SiteApi.apply(this, arguments);
// further construction
this.admin_method1 = function () {/* some admin instance method */};
}
SiteApi.prototype = Object.create(old_SiteApi.prototype);
// add more prototype things
SiteApi.prototype.admin_method2 = function () {/* admin stuff through prototype */},
return SiteApi;
}(SiteApi));
选项 2
让 SiteApi
知道稍后会有更多内容,例如原来的定义会变成
var SiteApi = (function () {
function SiteApi(initially) {
//stuff
var i;
for (i = 0; i < SiteApi.Extras.length; ++i) {
SiteApi.Extras[i].apply(this);
}
}
SiteApi.Extras = [];
SiteApi.prototype.method1 = function () {/* stuff */};
SiteApi.prototype.method2 = function () {/* stuff */};
return SiteApi;
}());
那么admin.js就可以了
SiteApi.Extras.push(
function () {
// stuff to make `this` into an Admin object
this.admin_method1 = function () {/* some admin instance method */};
}
);
选项 3
SiteApi
的原型仍然暴露,如果你不需要做更多的构造,只需要新的方法,你可以简单地在admin.js
Object.assign(SiteApi.prototype, {
admin_method1: function () {/* admin stuff through prototype */},
admin_method2: function () {/* more admin stuff through prototype */}
});
最后一个选项是唯一会影响在 admin.js 加载之前创建的 SiteApi 实例的选项。
当然,您也可以将选项 2 和 3 混合在一起。同样,您可以使用选项 1,但将新构造函数称为不同的名称,而不是隐藏原始构造函数,例如 AdminApi,并使用它代替 SiteApi ] 在管理页面上。
我的应用程序有一个 api 包装器 class 最初是通过在 TypeScript 中输入它创建的,copying/pasting javascript 到我的应用程序中。
所以 class def 看起来像这样:
var SiteApi = (function () {
function SiteApi(initially)
{
//stuff
}
SiteApi.prototype.method1 = function(){/*stuff*/};
SiteApi.prototype.method2 = function(){/*stuff*/};
return SiteApi;
})();
现在,当它们位于管理页面时,我想添加一个额外的 admin.js 文件,其中将包含管理方法。例如
SiteApi.prototype.Admin.method1 = function(){/*stuff*/};
我找到了一个可以实现我想要的 "end result" 的示例:
// file main
function SomeObject() {
for (var i = 0, ii = SomeObject.Partial.length; i < ii; i++) {
SomeObject.Partial[i].apply(this, arguments);
}
}
SomeObject.Partial.SomeName = function() {
...
}
// file extra
SomeObject.Partial.SomeOtherName = function() {
...
}
(来自:Is it possible to give javascript partial class behavior like C# or monkey patching like Ruby does?)
但是,他们使用的 class 定义类型不同。
如何在保持 TypeScript 风格 class 定义的同时做一些类似于此示例的操作来添加管理功能?
作为参考,我们这样使用 class:
siteApi = new SiteApi();
所以我想还需要一行代码将管理功能绑定到其中。
注意,我可以使用 SiteApi.admin_method1
之类的东西,但问题是使用 TypeScript 样式 classes 原型是在定义中定义的,对象是执行的,所以它不会以后如何添加更多原型似乎很简单。
选项 1
扩展 SiteApi
但隐藏原始内容,例如您之后加载的 admin.js 会包含类似
SiteApi = (function (old_SiteApi) {
function SiteApi() {
old_SiteApi.apply(this, arguments);
// further construction
this.admin_method1 = function () {/* some admin instance method */};
}
SiteApi.prototype = Object.create(old_SiteApi.prototype);
// add more prototype things
SiteApi.prototype.admin_method2 = function () {/* admin stuff through prototype */},
return SiteApi;
}(SiteApi));
选项 2
让 SiteApi
知道稍后会有更多内容,例如原来的定义会变成
var SiteApi = (function () {
function SiteApi(initially) {
//stuff
var i;
for (i = 0; i < SiteApi.Extras.length; ++i) {
SiteApi.Extras[i].apply(this);
}
}
SiteApi.Extras = [];
SiteApi.prototype.method1 = function () {/* stuff */};
SiteApi.prototype.method2 = function () {/* stuff */};
return SiteApi;
}());
那么admin.js就可以了
SiteApi.Extras.push(
function () {
// stuff to make `this` into an Admin object
this.admin_method1 = function () {/* some admin instance method */};
}
);
选项 3
SiteApi
的原型仍然暴露,如果你不需要做更多的构造,只需要新的方法,你可以简单地在admin.js
Object.assign(SiteApi.prototype, {
admin_method1: function () {/* admin stuff through prototype */},
admin_method2: function () {/* more admin stuff through prototype */}
});
最后一个选项是唯一会影响在 admin.js 加载之前创建的 SiteApi 实例的选项。
当然,您也可以将选项 2 和 3 混合在一起。同样,您可以使用选项 1,但将新构造函数称为不同的名称,而不是隐藏原始构造函数,例如 AdminApi,并使用它代替 SiteApi ] 在管理页面上。