typescript 有没有办法使用打字稿将方法动态添加到类中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12698893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to add methods on the fly to a class using typescript?
提问by pllee
I am trying create some kind of mixin method that add methods to the prototype/class on the fly but I get errors such as
我正在尝试创建某种混合方法,可以动态地向原型/类添加方法,但出现错误,例如
The property 'greetName' does not exist on value of type 'Greeter' any
'Greeter' 类型的值不存在属性 'greetName' 任何
and
和
The property 'greetName' does not exist on value of type 'Greeter' any
'Greeter' 类型的值不存在属性 'greetName' 任何
when I run the following code.
当我运行以下代码时。
class Greeter {
greeting: string;
constructor (message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
Greeter.prototype.greetName = function(name){
return this.greet() + ' ' + name;
}
var greeter = new Greeter('Mr');
window.alert(greeter.greetName('Name'));
It actually compiles to valid js and runs as expected. Is there a way to do this with out compiler warnings/errors?
它实际上编译为有效的 js 并按预期运行。有没有办法在没有编译器警告/错误的情况下做到这一点?
采纳答案by Fenton
This solution has the benefit of giving you type checking when you dynamically add a method:
此解决方案的好处是在您动态添加方法时为您提供类型检查:
class MyClass {
start() {
}
}
var example = new MyClass();
// example.stop(); not allowed
interface MyClass {
stop(): void;
}
MyClass.prototype['stop'] = function () {
alert('Stop');
}
var stage2 = example;
stage2.stop();
回答by Steven Ickman
They would need a concept of partial classes for this to work which currently isn't supported. I'll tell you that what I've found works better for these types of scenarios is to use interfaces instead (I've been programming in TypeScript for about 6 months now - I'm at MS but not on the TypeScript team)
他们需要一个部分类的概念才能使其工作,但目前尚不支持。我会告诉你,我发现对这些类型的场景更有效的是使用接口(我已经用 TypeScript 编程了大约 6 个月了 - 我在 MS 但不在 TypeScript 团队)
Interfaces are extensible after the fact by simply definging the methods you're adding to the interface. As an example of this, if you install a jQuery plugin you'll want to re-define the IJQuery & IJQueryUtil interface to include the plugins additional methods. From that point forward you can invoke the plugins methods through $.plugin() and TypeScript will be happy.
通过简单地定义您添加到接口的方法,接口在事后是可扩展的。例如,如果您安装了 jQuery 插件,您将需要重新定义 IJQuery 和 IJQueryUtil 接口以包含插件附加方法。从那时起,您可以通过 $.plugin() 调用插件方法,TypeScript 会很高兴。
回答by James Hancock
There is another way to do this.
还有另一种方法可以做到这一点。
Greeter["SomeProperty"] = function() {
return "somevalue";
};
Works the same and uses the property indexer function in javascript and typescript doesn't complain.
工作原理相同,并在 javascript 中使用属性索引器功能,打字稿不会抱怨。
回答by Schmoo
Similar to @Fenton example, but without the gnarly stuff:
类似于@Fenton 示例,但没有粗糙的东西:
class MyClass {
start() {
}
}
MyClass.prototype['stop'] = function () {
alert('Stop');
}
interface MyClass {
stop(): void;
}
var example = new MyClass();
example.stop(); // Allowed!!!
回答by Milad
This is how RxJSdoes it
这是怎么RxJS做的
import {Observable} from "./observable"; // which is Greeter in your case
declare module "./observable" {
interface Observable<T> {
map<U>(f: (x: T) => U): Observable<U>;
}
}
Observable.prototype.map = function (f) {
}
This is called Module Augmentation.
这称为模块增强。
回答by johnrcui
After having to implement dynamic methods and properties on classes, this was the solution I was able to go with to prevent Typescript compiler from complaining:
在必须在类上实现动态方法和属性后,这是我能够使用的解决方案,以防止 Typescript 编译器抱怨:
...
window.alert(greeter['greetName']('Name'));
Basically, use the bracket method of property accessors.
基本上,使用属性访问器的括号方法。

