TypeScript扩展String Static

max*_*dbe 7 typescript

有没有办法将isNullOrEmpty(str:string)添加到静态字符串对象.

这样我就可以称之为:

String.isNullOrEmpty(myobj);
Run Code Online (Sandbox Code Playgroud)

我已经找到了一种方法来实现它,但这对于像这样的方法没有帮助.

SWe*_*eko 14

Stringlib.d.ts使用以下接口定义

interface StringConstructor {
  ...
}

declare var String: StringConstructor;
Run Code Online (Sandbox Code Playgroud)

因此,虽然您无法向变量添加方法,但可以使用将它们添加到接口

interface StringConstructor {
   isNullOrEmpty(str:string):boolean;
}
Run Code Online (Sandbox Code Playgroud)

并使用它们在变量上实现它们

String.isNullOrEmpty = (str:string) => !str;
Run Code Online (Sandbox Code Playgroud)


Jef*_*ski 5

TypeScript进行称为声明合并的操作,在规范的 10.5节中对此进行了说明

要点是可以将成员放入foo模块中,然后再将更多成员放入foo模块中。从0.9开始,只要首先声明该类,它就可以将成员也放置在类的名称空间中。这是一个新功能,我已经发现了一些错误,但是应该可以使用。

因此,要专门回答您的问题,您可以执行以下操作:

module String {
    export function isNullOrEmpty(s: string): boolean {
        return !s;
    }
}

var s: string;
alert(String.isNullOrEmpty(s).toString());    // true
s = "";
alert(String.isNullOrEmpty(s).toString());    // true
s = "asdf";
alert(String.isNullOrEmpty(s).toString());    // false
Run Code Online (Sandbox Code Playgroud)

试试看


显然我的答案是不完整的,因为String被声明为var而不是模块。声明合并不会延续到vars(从0.9开始),这很烦人。尽管有点hack,但仍然有解决方法:

// filea.ts
module String {
    export function isNullOrEmpty(s: string): boolean {
        return !!s;
    }
}
module mynamespace {
    export declare var String: {
        new (value?: any): String;
        (value?: any): string;
        prototype: String;
        fromCharCode(...codes: number[]): string;
        isNullOrEmpty(s: string): boolean;
    }
}

// fileb.ts
/// <reference path="filea.ts" />
module mynamespace {
    var s: string;
    String.isNullOrEmpty(s);    // true
    s = "";
    String.isNullOrEmpty(s);    // true
    s = "asdf";
    String.isNullOrEmpty(s);    // false
}
Run Code Online (Sandbox Code Playgroud)

发生的事情filea是您在var String上放置了一个函数,然后声明mynamespace.Stringlib.d.ts中String的所有内容都存在,并加上了您添加的内容。然后,只要您在工作mysnamespace,对String的引用都将假定您在谈论mynamespace.String。那实际上并不存在,所以您会得到想要的String。

就像我说的那样,这有点脏,但是假设您遵循不错的名称空间约定,则应该有一个顶级名称空间,您只需执行一次即可。但是,如果您想将String扩展名共享为库的一部分,那么……您会陷入困境。