基类型字符串上的TypeScript重载方法

时间:2015-10-15 15:10:17

标签: javascript typescript overloading

TypeScript-Version:1.6

我试图为String s replace - 函数添加另一个重载函数,该函数应具有以下签名:

replace(searchValue: string, replaceValue: any): string;

所以它可以像

一样使用
"someString".replace("replaceMe", $(evt.target).data("row-id"))

我需要any .data定义为:

data(key: string): any;

我的String.d.ts(声明)

interface String {
    /**
      * Replaces text in a string, using a regular expression or search string.
      * @param searchValue A string that represents the regular expression.
      * @param replaceValue A string containing the text to replace for every successful match of searchValue in this string.
      */
    replace(searchValue: string, replaceValue: any): string;
}

我的String.ts(实施)

String.prototype.replace = (searchValue: string, replaceValue: any):string =>
{
    if (replaceValue instanceof String) {
        var stringReplacement = replaceValue.toString();
        return String.prototype.replace(stringReplacement, replaceValue);
    } else {
        return replaceValue;
    }
}

抛出以下错误,我不确定原因以及如何修复:

  

错误TS2322类型'(searchValue:string,replaceValue:any)=>字符串'不能赋值类型' {(searchValue:string,replaceValue:string):string; (searchValue:string,replacer :( substring ...'。   参数类型' searchValue'和' searchValue'是不相容的。   输入' string'不能分配给' RegExp'。   财产' exec'在'字符串'。

中缺少

编辑#1

我最后只得到replace的声明(以及删除实现)以满足编译器:

interface String {
    /**
      * Replaces text in a string, using a regular expression or search string.
      * @param searchValue A string that represents the regular expression.
      * @param replaceValue A string containing the text to replace for every successful match of searchValue in this string.
      */
    replace(searchValue: string, replaceValue: any): string;
}

这仍然是错误的,因为它在内部仍然调用库的replace - 函数?

编辑#2

如果没有使用任何自己的Visual Studio正在大喊

Withour cast

使用强制转换显示(ReSharper)

ReSharper says

使用示例4.1(MartyIX)

With variable declaration

2 个答案:

答案 0 :(得分:2)

执行"someString".replace("replaceMe", $(evt.target).data("row-id"));应该有效,因为any可以分配给string。我不确定您收到错误的原因,但我建议您确保string作为replace的第一个参数的功能签名尚未从lib.d.ts中移除。您可以通过转到replace的定义(将光标置于替换并按F12)并确保它具有下面显示的所有功能签名来仔细检查。您也可以尝试暂时禁用resharper以查看是否会导致错误消失。

顺便说一下,为了通过覆盖String.prototype.replace修复错误,它已经有了这些可能的函数签名:

replace(searchValue: string, replaceValue: string): string;
replace(searchValue: string, replacer: (substring: string, ...args: any[]) => string): string;
replace(searchValue: RegExp, replaceValue: string): string;
replace(searchValue: RegExp, replacer: (substring: string, ...args: any[]) => string): string;

searchValueRegExp时,写入的内容不兼容,因此您需要通过使用联合类型更改函数签名以允许stringRegExp

String.prototype.replace = function(searchValue: string | RegExp, replaceValue: any) {
    // omitted
}

我不确定你要做什么,因为这个函数会做一个无限循环。也许你的意思是保留对原始String.prototype.replace的引用并称之为?请记住,当您分配到String.prototype.replace时,您会覆盖原始功能。

总体而言,不要做这里正在做的事情。查找“不要修改你不拥有的对象”,看看我的意思。如果您创建自己的单独函数来执行此操作会更好,因为现在这个替换函数会破坏使用它的任何代码。如果您使用的任何库使用replace方法,您将会遇到非常奇怪的行为,并且很难跟踪问题。

答案 1 :(得分:0)

我对此的看法:

1)以下代码不会在我的机器上报告任何错误:

/// <reference path="typings/jquery/jquery.d.ts" />

"someString".replace("replaceMe", $('#test').data("row-id"));

您确定首先出现问题吗?您对TypeScript编译器的设置是什么(即如何编译TS代码)?

2)如果您需要实施replace方法,您应该考虑为此创建自己的模块,否则您可能会对阅读代码的人造成极大的混淆:

module Project.Utils {
    export class String {   
        public replace = (searchValue: string, replaceValue: any):string =>
        {
            // some replace implementation
        }
    }
}

3)首先实现是错误的,因为你替换String.prototype.replace然后你希望它会调用String.prototype.replace的本机实现,但事实并非如此。实际上,您的实现根本不会执行任何替换功能。

String.prototype.replace = (searchValue: string, replaceValue: any):string =>
{
    if (replaceValue instanceof String) {
        var stringReplacement = replaceValue.toString();
        return String.prototype.replace(stringReplacement, replaceValue);
    } else {
        return replaceValue;
    }
}

4)此代码在http://www.typescriptlang.org/Playground中完全正常:

let n:any = 1; 
"someString".replace("replaceMe", n); 

"someString".replace("replaceMe", <any>5); // explicit cast