【问题标题】:TypeScript extend String StaticTypeScript 扩展字符串静态
【发布时间】:2013-07-24 11:20:04
【问题描述】:

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

我可以这样称呼它:

String.isNullOrEmpty(myobj);

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

【问题讨论】:

  • 您是否有理由不能使用! 运算符?例如:if(!str) { ... }?
  • 大部分我只是用这个作为例子
  • 例如什么?我的意思是您是否对如何检查空字符串特别感兴趣,或者您是否想要关于如何扩展现有对象(如字符串)的一般答案?

标签: typescript


【解决方案1】:

Stringlib.d.ts中定义,接口如下

interface StringConstructor {
  ...
}

declare var String: StringConstructor;

因此,虽然您不能将方法添加到变量中,但您可以使用

将它们添加到接口中
interface StringConstructor {
   isNullOrEmpty(str:string):boolean;
}

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

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

【讨论】:

  • 这是否也可以通过 ArrayConstructor 使用 Array 类型?
  • 这应该可以,但请注意有两个接口,通用Array<T> 和非通用ArrayConstructor
【解决方案2】:

TypeScript 做了一种叫做声明合并的事情,这在the spec 的第 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

Try it out.


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

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

就像我说的那样,它有点脏,但假设你关注的是体面的namespace conventions,你应该有一个顶级命名空间,你只需要这样做一次。但是,如果您想将字符串扩展作为库的一部分共享……那么您就被卡住了。

【讨论】:

  • 它按预期在操场上工作,但是将其分成两个 ts 文件并引用 string.d.ts 一个不允许您按预期使用它
  • 啊,你是对的。 lib.d.ts String 中存在的问题被声明为 var (显然不符合合并条件)而不是模块。我不认为你可以在同一个命名空间中重新声明一个 var,但你可以在不同的命名空间中声明。我会修改我的答案来解释它。
【解决方案3】:

我的解决方案使用不同的方法,因为此阶段的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"));

演示:TypeScriptPlayground

【讨论】:

    猜你喜欢
    • 2016-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多