2013-09-16 3 views
9

Я пытаюсь переписать некоторый код моего JavaScript в TypeScript. Некоторые из этого кода имеют ссылки на расширение, которое я добавил к прототипу строкового объекта.Расширение базовых типов в TypeScript, ошибка: «_this is not defined ...»

String.prototype.format = function() { 
    var formatted = this; 
    for (var i = 0; i < arguments.length; i++) { 
     formatted = formatted.replace(
      RegExp("\\{" + i + "\\}", 'g'), arguments[i].toString()); 
    } 
    return formatted; 
}; 

Однако добавление этого сценария типа было довольно сложным.

Я видел примеры, когда вы объявляете расширение базового интерфейса, а затем назначаете функцию прототипу в соответствии с интерфейсом и предоставляете свою функциональность. Как и ...

interface String { 
    showString:() => string; 
} 

String.prototype.showString =(): string { 
    return this; 
}; 

Кроме этого ошибки, потому что «_this не определен ...»

Другие вещи, я пытался это создать новый класс для расширения строки ...

export class MoreString extends string { 

} 

Однако это также не работает, потому что вы можете только расширять классы, а string/String - это не классы, а встроенные типы.

Каков самый простой способ расширения String и доступа к моему методу расширения?

ответ

11

я в конечном итоге работаю на другой вопрос позже в тот же день, что заставило меня посмотреть, что здесь происходит. С вершины, здесь это ...

TypeScript построен поверх JavaScript, так что @Nypan говорит, что JavaScript действителен для TypeScript. Из-за этого различия очень легко упускать из виду.

Функция JavaScript, подобная этой, ссылается на область действия, выполняемую функцией с помощью «этого».

var f = function (postFix) {return this + postFix}; 

Чтобы добавить синтаксис машинопись вы бы определить типы

var f = function (postFix: string): string {return this + postFix}; 

В обоих случаях это относится к области видимости функции так же, как классический JavaScript. Тем не менее, ситуация не изменится, когда мы делаем это ...

var f = (postFix: string): string {return this + postFix}; 
//or more correctly 
var f = (postFix: string): string => {return this + postFix}; 

При удалении функции от перед параметрами, то это уже не классическая функция. Он становится функцией «Fat Arrow», видимо, даже без использования синтаксиса «=>». В приведенных выше примерах «это» теперь относится к классу, который существует в C#.

В моей попытке назначить функцию прототипу строки я опустил ключевое слово функции, поэтому оно было интерпретировано как функция «Fat Arrow» и пытается связать это с областью действия класса. Однако функциональная доза не существует в классе и вызывает ошибку «это не определено».

Когда я добавляю ключевое слово «функция», функция интерпретируется так, как я намеревался и работает правильно.

interface String { 
    format:() => string; 
} 

String.prototype.format = function() : string { 
    var formatted = this; 
    for (var i = 0; i < arguments.length; i++) { 
     formatted = formatted.replace(
      RegExp("\\{" + i + "\\}", 'g'), arguments[i].toString()); 
    } 
    return formatted; 
}; 
2

В точности похож случае я делаю это так:

interface String { 
    endsWith(str); 
    startsWith(str); 

} 

Это просто, чтобы удовлетворить компилятор. Вы реализуете методы точно так же, как в javascript.

Надеюсь, что это поможет.

2

Я думаю, что это то же самое, что и шаг, но вы просто расширяете его в javascript (javascript является допустимым машинописным текстом), а затем взаимодействуете с новой функциональностью.

Краткий пример:

String.prototype.myExtension = function() { 
    return this + " something." 
}; 

interface String { 
    myExtension :() => string; 
} 

alert("test".myExtension()); 
+1

Но где в код вы добавляете это определение? потому что я получаю свойство 'myExtension' не существует в типе 'String', поэтому он не компилируется. У меня есть эта часть кода внутри определения модуля. – Oscar

+0

Это работало для меня, TANKS! – Benoit

+0

@ Оскар же, не работает на моем –

1

Вам необходимо расширить интерфейс String, как это:

interface String { 
    stringFormat(...args: string[]): string; 
} 

и вам нужно реализовать как этот источник

module Utilities { 
    String.prototype.stringFormat = function(): string { 
     var args = arguments; 
     return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (m, n) { 
      if (m == "{{") { return "{"; } 
      if (m == "}}") { return "}"; } 
      return args[n]; 
     }); 
    } 
} 

реализации: Equivalent of String.format in jQuery

+0

Важность «модуля Утилиты» ... СПАСИБО! – mlorber

Смежные вопросы