有没有办法使用typescript动态添加方法?

时间:2012-10-02 21:49:46

标签: typescript

我正在尝试创建某种mixin方法,即动态地将方法添加到原型/类中,但是我遇到了错误,例如

  

属性'greetName'在类型'Greeter'的值上不存在   任何

  

属性'greetName'在类型'Greeter'的值上不存在   任何

当我运行以下代码时。

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'));

它实际上编译为有效的js并按预期运行。有没有办法在编译器警告/错误的情况下执行此操作?

6 个答案:

答案 0 :(得分:16)

此解决方案的好处是可以在动态添加方法时进行类型检查:

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();

答案 1 :(得分:8)

他们需要一个部分类的概念来实现,目前不支持。我会告诉你,我发现对于这些类型的场景更有效的方法是使用接口(我已经在TypeScript中编程了大约6个月 - 我在MS但不在TypeScript团队中)< / p>

接口可以通过简单地定义您添加到接口的方法来扩展。作为一个例子,如果您安装一个jQuery插件,您将需要重新定义IJQuery&amp; IJQueryUtil接口包含插件的附加方法。从那时起,您可以通过$ .plugin()调用插件方法,TypeScript会很高兴。

答案 2 :(得分:8)

还有另一种方法可以做到这一点。

Greeter["SomeProperty"] = function() {
     return "somevalue";
};

工作相同并在javascript中使用属性索引器函数,并且打字稿不会抱怨。

答案 3 :(得分:2)

与@Fenton示例类似,但没有粗糙的东西:

class MyClass {
    start() {
    }
}
MyClass.prototype['stop'] = function () {
    alert('Stop');
}

interface MyClass {
    stop(): void;
}

var example = new MyClass();
example.stop(); // Allowed!!!

答案 4 :(得分:1)

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) {

}

这称为模块增强。

答案 5 :(得分:0)

在必须在类上实现动态方法和属性之后,这是我能够使用的解决方案来阻止Typescript编译器抱怨:

...
window.alert(greeter['greetName']('Name'));

基本上,使用property accessors的括号方法。