在Typescript 2.8 +

时间:2018-04-25 23:47:04

标签: interface typescript2.0

这不起作用

interface String {
    contains(s:string):boolean;
}
String.prototype.contains=(s:string):boolean=>this.indexOf(s)!==-1;

因为Property 'contains' does not exist on type 'String'

这有点令人惊讶,因为添加它是接口声明的全部要点。 http://www.typescriptlang.org/docs/handbook/declaration-merging.html表明上述代码是合法的。据我所知,String位于全局命名空间中,通过检查lib.es2015.wellknown.d.ts

正确的方法是什么?读完Aluan Haddad的Extending third party module that is globally exposed后,我改写了这个

declare global {
    interface String {
        contains(s: string): boolean;
    }
}
String.prototype.contains=(s:string):boolean=>this.indexOf(s)!==-1;

现在界面更改正确。但现在'this' implicitly has type 'any' because it does not have a type annotation.

进一步的评论this可以使用函数语法显式输入。

String.prototype.contains = function (this: string, s:string):boolean { 
    return this.indexOf(s)!==-1; 
};

还应该注意的是,在本调查过程中,我发现contains使用名称includes实施,并在lib.es2015.core.d.ts

中声明

1 个答案:

答案 0 :(得分:0)

如果您正在定义模块内部的扩充,即包含顶级importexport的文件,那么您需要在declare global块中使用this块为了扩大全球范围。否则,您声明的接口将不会合并到全局数组接口中,因为它与任何其他声明一样是模块的本地接口。声明全局语法专门用于涵盖此用例。

此外,当您定义实际方法时,如果方法本身是根据this定义的,则您不能使用箭头函数,因为箭头函数具有静态范围this而动态方法需要// this is a module export {} declare global { interface String { contains(other: string): boolean; } } String.prototype.contains = function (other) { return this.indexOf(other) and !== -1; };

把它放在一起

<app-app1 id="id1"></app-app1>
<app-app2 id="id2"></app-app2>
<app-app3 id="id3" *ngIf="test"></app-app3>

请注意,无论要扩充的类型是类还是接口,都需要在接口中声明成员,因为接口可以与类合并,接口可以与接口合并但类不合并。