TypeScript 中的简单扩展方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13229044/
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
Simple extension method in TypeScript
提问by
I'm trying to create an extension method for class but seems something is wrong. Below is the code, the output JS-file is correct but the compiler twice times shows an error "test.ts(10,16): The property 'close' does not exist on value of type 'Test'"What should be corrected ?
我正在尝试为类创建一个扩展方法,但似乎有些问题。下面是代码,输出 JS 文件是正确的,但编译器两次显示错误“test.ts(10,16): The property 'close' does not exist on value of 'Test'”应该更正什么?
class Test {
}
interface Test
{
close():any;
}
Test.prototype.close = function() {}
var t = new Test();
t.close();
Update: The code above is compiled okay with built-in types. I need to extend my own classes.
更新:上面的代码可以用内置类型编译。我需要扩展我自己的类。
Update 2: Old compiler version issue. Currently all is okay!
更新 2:旧的编译器版本问题。目前一切正常!
回答by Fenton
This example uses inheritance to extend the original object. The naming is just for illustration.
本示例使用继承来扩展原始对象。命名只是为了说明。
class Test {
baseMethod() {
}
}
class TestWithClose extends Test {
close() {
}
}
var t = new TestWithClose();
t.close();
t.baseMethod();
Update
更新
You have mentioned in your comment that you can write extension methods for built-in functions in the way you want and I can see that you want to do the same for your own code, but that isn't possible.
您在评论中提到您可以按照您想要的方式为内置函数编写扩展方法,我可以看到您想为自己的代码做同样的事情,但这是不可能的。
I hope this explains why.
我希望这能解释原因。
When you create a declaration in TypeScript, you can extend that declaration by adding to it. You can either use the declare keyword or place the file in a .d.ts
file:
在 TypeScript 中创建声明时,可以通过添加来扩展该声明。您可以使用声明关键字或将文件放在.d.ts
文件中:
For example, if you have this declaration in one file:
例如,如果您在一个文件中有此声明:
declare interface ExampleInterface {
methodOne();
}
You can extend the declaration in another file:
您可以在另一个文件中扩展声明:
declare interface ExampleInterface {
methodTwo();
}
So when you use it, you have both functions available:
所以当你使用它时,你有两个功能可用:
function example(example: ExampleInterface) {
example.methodOne();
example.methodTwo();
}
These aren't really extension methods - this is just telling the compiler about an implementation in more than one go. This is particularly useful for jQuery as it allows each plugin to have a definition that adds to the JQuery
interface.
这些并不是真正的扩展方法——这只是告诉编译器不止一次的实现。这对 jQuery 尤其有用,因为它允许每个插件都有一个添加到JQuery
界面的定义。
You can't do this for you own TypeScript code, because adding to an interface will cause all implementations to require an update to match the interface definition.
您不能为自己的 TypeScript 代码执行此操作,因为添加到接口将导致所有实现都需要更新以匹配接口定义。
The mind-shift here is that TypeScript is giving you static typing and you are looking for dynamic behaviour - so you have to choose one or the other. For example, you can just use dynamic behaviour where you really want it and leave the rest statically typed:
这里的转变是 TypeScript 为您提供静态类型,而您正在寻找动态行为 - 因此您必须选择其中之一。例如,您可以只在您真正需要的地方使用动态行为,而让其余的静态类型:
class Test {
}
// statically typed
var stTest = new Test();
// dynamically typed
var testExtender: any = Test;
testExtender.prototype.close = function() {
alert('Close');
};
var t: any = new Test();
t.close();
That isn't to say something won't be added to the language in the future to support extension methods.
这并不是说将来不会在语言中添加一些东西来支持扩展方法。