2013-11-19 2 views
25

String.Format не работает в TypeScript.
Ошибка:String.Format не работает в TypeScript

The property 'format' does not exist on value of type 
'{ prototype: String; fromCharCode(...codes: number[]): string; 
(value?: any): string; new(value?: any): String; }'. 

attributes["Title"] = String.format(
    Settings.labelKeyValuePhraseCollection["[WAIT DAYS]"], 
    originalAttributes.Days 
); 
+3

Почему, на ваш взгляд, 'String.format' существует из коробки? – VisioN

+1

Итак, как я могу добавить String.format? –

ответ

3

Вы можете объявить сам довольно легко:

declare module String{ 
    export var format:any; 
} 

String.format('',''); 

Это предполагает, что string.Format является определяется в другом месте. например в Microsoft Ajax Toolkit: http://www.asp.net/ajaxlibrary/Reference.String-format-Function.ashx

+0

Существует уже интерфейс для 'String' в lib.d.ts, поэтому вы можете просто расширить его, поскольку интерфейсы открыты. – Fenton

+0

Невозможно переопределить переменную «String» с блочной областью. –

63

Строка Интерполяция

Примечание: На машинопись 1.4, строка интерполяции доступна в машинописном:

var a = "Hello"; 
var b = "World"; 

var text = `${a} ${b}` 

Это будет компилировать:

var a = "Hello"; 
var b = "World"; 
var text = a + " " + b; 

Строка Формат

JavaScript String объект не имеет функции format. ТипScript не добавляет к собственным объектам, поэтому он также не имеет функции String.format.

Для машинопись, вам необходимо расширить интерфейс String, а затем вам нужно, чтобы поставлять implementation:

interface String { 
    format(...replacements: string[]): string; 
} 

if (!String.prototype.format) { 
    String.prototype.format = function() { 
    var args = arguments; 
    return this.replace(/{(\d+)}/g, function(match, number) { 
     return typeof args[number] != 'undefined' 
     ? args[number] 
     : match 
     ; 
    }); 
    }; 
} 

Вы можете использовать функцию:

var myStr = 'This is an {0} for {0} purposes: {1}'; 

alert(myStr.format('example', 'end')); 

Вы могли также рассмотреть string interpolation (особенность шаблонных строк), которая является функцией ECMAScript 6 - хотя для ее использования в случае использования String.format вам все равно нужно будет обернуть ее в функцию, чтобы поставьте необработанную строку, содержащую формат, а затем позиционные аргументы. Он чаще используется inline с переменными, которые интерполируются, поэтому вам нужно сопоставить аргументы, чтобы они работали для этого прецедента.

Например, формат строки, как правило, определяется для последующего использования ... который не работает:

// Works 
var myFormatString = 'This is an {0} for {0} purposes: {1}'; 

// Compiler warnings (a and b not yet defines) 
var myTemplateString = `This is an ${a} for ${a} purposes: ${b}`; 

Так использовать интерполяцию строки, а не формат строки, вы должны использовать:

function myTemplate(a: string, b: string) { 
    var myTemplateString = `This is an ${a} for ${a} purposes: ${b}`; 
} 

alert(myTemplate('example', 'end')); 

Другой распространенный вариант использования для строк формата - это то, что они используются как общий ресурс. Я еще не нашел способ загрузить строку шаблона из источника данных, не используя eval.

+0

«JavaScript (** и поэтому TypeScript **) не имеет встроенной функции String.Format» - на самом деле это неверно. Есть много вещей, которые существуют в TypeScript *, которые не существуют в JavaScript * (наоборот, вы сказали, что это правда, однако) –

+1

@YannDuran вы можете дать мне пример одного родного объекта, который был расширен в языке TypeScript? В заявлении указывается, что во время выполнения вы будете называть точно такой же объект «String», как кто-то, использующий JavaScript. – Fenton

+0

Я ничего не сказал о том, что какой-либо родной объект расширяется в TypeScript, я сказал, что ваше утверждение, как вы его написали, неверно. Type Script - это надмножество ** Javascript, поэтому в языке TypeScript существует много конструкций, которые не существуют в Javascript. [«С выпуском версии 1.4 TypeScript теперь поддерживает строки шаблонов ES6 и может также скомпилировать их до выражений ES3/ES5»] (http://blogs.msdn.com/b/typescript/archive/2015/01/16/announcing -typescript-1-4.aspx). Вы использовали бы это вместо этого, если string.format достигнет того же результата. –

18

Вы можете использовать встроенную строку интерполяции машинопись в том случае, если ваша единственная цель устранить уродливые конкатенации строк и скучные преобразования строки:

var yourMessage = `Your text ${yourVariable} your text continued ${yourExpression} and so on.` 

ПРИМЕЧАНИЕ: В правой части оператора присваивания разделители не являются ни одного или двойные кавычки, вместо этого специальный символ называется backtick или серьезный акцент.

Компилятор TypeScript переводит специальный литерал правой стороны в выражение конкатенации строк. Другими словами, этот синтаксис не использует функцию ECMAScript 6, а не родную функцию TypeScript. Ваш сгенерированный код javascript остается совместимым.

+1

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

+0

Приятно слышать, что сейчас это работает –

1

FIDDLE:https://jsfiddle.net/1ytxfcwx/

НПМ:https://www.npmjs.com/package/typescript-string-operations

GitHub:https://github.com/sevensc/typescript-string-operations

я реализовал класс для String. Это не идеально, но это работает для меня.

использовать это то, как это:

var getFullName = function(salutation, lastname, firstname) { 
    return String.Format('{0} {1:U} {2:L}', salutation, lastname, firstname) 
} 

export class String { 
    public static Empty: string = ""; 

    public static isNullOrWhiteSpace(value: string): boolean { 
     try { 
      if (value == null || value == 'undefined') 
       return false; 

      return value.replace(/\s/g, '').length < 1; 
     } 
     catch (e) { 
      return false; 
     } 
    } 

    public static Format(value, ...args): string { 
     try { 
      return value.replace(/{(\d+(:.*)?)}/g, function (match, i) { 
       var s = match.split(':'); 
       if (s.length > 1) { 
        i = i[0]; 
        match = s[1].replace('}', ''); 
       } 

       var arg = String.formatPattern(match, args[i]); 
       return typeof arg != 'undefined' && arg != null ? arg : String.Empty; 
      }); 
     } 
     catch (e) { 
      return String.Empty; 
     } 
    } 

    private static formatPattern(match, arg): string { 
     switch (match) { 
      case 'L': 
       arg = arg.toLowerCase(); 
       break; 
      case 'U': 
       arg = arg.toUpperCase(); 
       break; 
      default: 
       break; 
     } 

     return arg; 
    } 
} 

EDIT:

я расширил класс и создал репозиторий на GitHub. Было бы здорово, если бы вы могли помочь улучшить его!

https://github.com/sevensc/typescript-string-operations

или загрузить пакет NPM

https://www.npmjs.com/package/typescript-string-operations

+0

Любой плункер или скрипка? – k11k2

+0

Здесь вы найдете: https: //jsfiddle.net/1ytxfcwx/ – seven

+0

хорошую работу, уже используя ваш пакет с небольшими изменениями. – k11k2

0

В качестве обходного пути, который достигает той же цели, вы можете использовать sprintf-js библиотеку и types.

Я получил его от другого SO answer.

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