29

我正在尝试创建某种 mixin 方法,可以即时向原型/类添加方法,但出现错误,例如

“Greeter”类型的值上不存在属性“greetName”

“Greeter”类型的值上不存在属性“greetName”

当我运行以下代码时。

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 并按预期运行。有没有办法在没有编译器警告/错误的情况下做到这一点?

4

6 回答 6

23

此解决方案的好处是在您动态添加方法时为您提供类型检查:

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();
于 2013-06-06T16:02:29.827 回答
9

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

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

工作原理相同,并在 javascript 中使用属性索引器功能,打字稿不会抱怨。

于 2012-12-19T15:06:05.360 回答
8

他们需要一个部分类的概念才能使其工作,目前不支持。我会告诉你,我发现对于这些类型的场景更有效的是使用接口来代替(我已经用 TypeScript 编程大约 6 个月了——我在 MS,但不在 TypeScript 团队)

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

于 2012-10-02T22:22:11.947 回答
3

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

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

interface MyClass {
    stop(): void;
}

var example = new MyClass();
example.stop(); // Allowed!!!
于 2018-05-26T14:16:22.117 回答
2

这是怎么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) {

}

这称为模块增强。

于 2018-10-23T00:21:30.917 回答
0

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

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

基本上,使用属性访问器的括号方法。

于 2016-08-26T01:56:18.133 回答