TypeScript 扩展字符串静态

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17843215/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 02:50:30  来源:igfitidea点击:

TypeScript extend String Static

typescript

提问by maxfridbe

Is there a way to add a isNullOrEmpty(str:string) to the static string object.

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

such that I can call it:

这样我就可以称之为:

String.isNullOrEmpty(myobj);

I have found a way to put it on the implementation but that does not help for a method such as this.

我找到了一种方法来实现它,但这对这样的方法没有帮助。

采纳答案by Jeffery Grajkowski

TypeScript does something called declaration merging, which is explained in section 10.5 of the spec.

TypeScript 做了一些称为声明合并的事情,这在规范的10.5 节中进行解释。

The gist of it is you can put members in module foo, and then later on put more members in module foo. As of 0.9 this extends to putting members in the namespace of a class as well, as long as the class is declared first. That's a new feature and I've discovered bugs around it, but it's supposed to work.

其要点是您可以将成员放入模块 foo 中,然后再将更多成员放入模块 foo 中。从 0.9 开始,只要首先声明类,这也扩展到将成员放入类的命名空间中。这是一个新功能,我发现了它周围的错误,但它应该可以工作。

So to answer your question specifically you can just do this:

因此,要具体回答您的问题,您可以这样做:

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

Try it out.

试试看



Apparently my answer is not complete because String is declared as a var and not a module. Declaration merging doesn't carry over to vars (as of 0.9) which is annoying. There is still a way around this though it's a bit of a hack:

显然我的答案不完整,因为 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
}

What's going on in fileais you're putting a function on the var String, and then declaring that mynamespace.Stringexists with everything String in lib.d.ts has plus what you added. Then, so long as you're working in mysnamespace, references to String will assume you're talking about mynamespace.String. That doesn't really exist so you'll get good ol' String which is what you want.

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

Like I said it's a bit dirty, but assuming you're following decent namespace conventionsyou should have a top level namespace where you only have to do this once. If you want to share the String extensions as part of a library though... well you're stuck.

就像我说的那样有点脏,但假设您遵循体面的命名空间约定,您应该有一个顶级命名空间,您只需执行一次。如果您想将字符串扩展名作为库的一部分共享……那么您就被卡住了。

回答by SWeko

Stringis defined in lib.d.tswith the following interface

Stringlib.d.ts在以下接口中定义

interface StringConstructor {
  ...
}

declare var String: StringConstructor;

so while you can't add methods to a variable, you can add them to the interface, using

所以虽然你不能向变量添加方法,但你可以将它们添加到接口中,使用

interface StringConstructor {
   isNullOrEmpty(str:string):boolean;
}

and them implement them on the variable, using

然后他们在变量上实现它们,使用

String.isNullOrEmpty = (str:string) => !str;

回答by d.danailov

My solution use different approach, because stringbase type in this phase cannot be extended.

我的解决方案使用不同的方法,因为string此阶段的基本类型无法扩展。

module Type {
    "use strict";

    export module BaseType {
        export class ApplicationString {

            /**
             * Indicates whether the specified string is null or an Empty string.
             *
             * @property string inputString
             * @see https://msdn.microsoft.com/en-us/library/system.string.isnullorempty(v=vs.110).aspx
             */
            static isNullOrEmpty(inputString: string): boolean {
                if (inputString === null || inputString.length === 0) {
                    return true;
                } else {
                    return false;
                }
            }
        }
    }
}

alert(Type.BaseType.ApplicationString.isNullOrEmpty(null));
alert(Type.BaseType.ApplicationString.isNullOrEmpty(""));
alert(Type.BaseType.ApplicationString.isNullOrEmpty("text"));

Demo: TypeScriptPlayground

演示:TypeScriptPlayground