2015-10-15 5 views
0

Машинопись-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 Тип '(searchV alue: string, replaceValue: any) => string 'не присваивается типу' {(searchValue: string, replaceValue: string): string; (searchValue: string, replacer: (substring ... '. Типы параметров «searchValue» и «searchValue» несовместимы. Тип «строка» не может быть присвоен типу «RegExp». Свойство «exec» отсутствует в типа 'String'

Редактировать # 1

Я в конечном итоге только с декларацией за replace (и removement реализации), чтобы удовлетворить компилятор:.

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 -функцию библиотеки?

Edit # 2

Если ничего не используя собственный Visual Studio орет

Withour cast

С броском он показывает (ReSharper)

ReSharper says

С примера 4.1 (MartyIX)

With variable declaration

+0

Так что, я ничего не знаю о машинописи знаю, но я не вижу, что делает этот метод, который вы не можете уже делать с 'String.prototype.replace'? – Mathletics

+0

Кажется, что функции TS являются инвариантными по типам параметров, а 'f (string, any)' не могут быть сохранены в значение типа 'f (string, string)'. –

+0

@Mathletics это ошибка во время компиляции, так как в машинописном тексте нет определения для 'replace (string, any)' – KingKerosin

ответ

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; 

Что было написано не совместим, когда searchValue является RegExp, так что вам нужно изменить функцию подписи, чтобы как string и RegExp с использованием типа накидной:

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

Я не уверен, что вы пытаетесь сделать, хотя, потому что функция будет делать бесконечная петля. Может быть, вы хотели провести ссылку на оригинал String.prototype.replace и назвать это? Помните, что при назначении String.prototype.replace вы перезаписываете исходную функцию.

В целом, не делайте то, что делается здесь. Посмотрите «не изменяйте объекты, которые у вас нет», чтобы понять, что я имею в виду. Было бы лучше, если бы вы создали свою собственную отдельную функцию, чтобы сделать это, потому что прямо сейчас эта функция замены прерывает любой код, который использует его. Вы получите очень странное поведение, если какая-либо используемая вами библиотека использует метод replace, и будет сложно отследить проблему.

+0

У меня есть смысл не делать то, что вы описали. Совершенно бессмысленно не касаться объектов, которые у меня нет. Я закончил с «Редактировать # 1» в моем вопросе. Это нормально? По крайней мере, я не хочу называть '.toString() 'каждый раз, чтобы удовлетворить компилятор – KingKerosin

+1

На мой взгляд, вы должны создать функцию, отличную от' interface String', которая будет делать то, что вы хотите. Например, 'StringUtils.myCustomReplaceFunction (" someString "," replaceMe ", $ (evt.target) .data (" row-id "));'. –

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 
+0

1) Он показывает мне ошибку, как описано в VS. Мои настройки должны использовать TSCompiler 1.6 в% programfiles% или вы имеете в виду другие настройки? 2) Хорошая точка, но мое редактирование (что делает 3) устаревшим), все еще не называя правильную «внутреннюю» замену? 3) Я удалил свою собственную реализацию 4) позвольте мне проверить – KingKerosin

+0

1) Вы указали ошибку для своей реализации _own_. Не для фактической команды: '" someString ".replace (" replaceMe ", $ (evt.target) .data (" row-id "))' –

+0

3) Когда вы удаляете свою собственную реализацию, это нормально. Поэтому 'edit # 1' является правильным решением. –