我正在尝试创建某种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并按预期运行。有没有办法在编译器警告/错误的情况下执行此操作?
答案 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的括号方法。