【问题标题】:String.Format not work in TypeScriptString.Format 在 TypeScript 中不起作用
【发布时间】:2013-12-02 22:10:14
【问题描述】:

String.FormatTypeScript 中不起作用。
错误:

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
);

【问题讨论】:

  • 为什么你认为String.format 是开箱即用的?
  • 那么如何添加String.format?

标签: javascript string typescript string-formatting


【解决方案1】:

您可以很容易地自己声明

interface StringConstructor {
    format: (formatString: string, ...replacement: any[]) => string;
}

String.format('','');

这是假设 String.format 在其他地方定义。例如在 Microsoft Ajax 工具包中:http://www.asp.net/ajaxlibrary/Reference.String-format-Function.ashx

【讨论】:

  • lib.d.ts 中已经有一个String 的接口,所以你可以在接口打开时扩展它。
  • 无法重新声明块范围变量“字符串”。
【解决方案2】:

字符串插值

注意:从 TypeScript 1.4 开始,TypeScript 中可以使用字符串插值:

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

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

这将编译为:

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

字符串格式

JavaScript String 对象没有 format 函数。 TypeScript 不会添加到本机对象,因此它也没有 String.format 函数。

对于 TypeScript,你需要扩展 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 用例,您仍然需要包装它在一个函数中,以便提供一个包含格式和位置参数的原始字符串。它更典型地与被插值的变量内联使用,因此您需要使用参数进行映射以使其适用于此用例。

例如,格式字符串通常定义为以后使用...这是行不通的:

// 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 从数据源加载模板字符串的方法。

【讨论】:

  • “JavaScript(因此 TypeScript)没有原生的 String.Format 函数”——这实际上是不正确的。 TypeScript 中存在许多 JavaScript 中不存在的东西(但与您所说的相反)
  • @YannDuran 你能给我一个关于一个在 TypeScript 中扩展的原生对象的例子吗?该声明指出,在运行时,您将调用与使用 JavaScript 的人完全相同的 String 对象。
  • 我没有说任何在 TypeScript 中扩展的本机对象,我说你写的陈述是不正确的。 Type Script 是 Javascript 的超集,因此 TypeScript 中存在许多 Javascript 中不存在的结构。 "With the 1.4 release, TypeScript now supports ES6 template strings and can also compile them down to ES3/ES5 expressions"。如果 string.format 达到相同的结果,您将使用它来代替。
  • @YannDuran 我已经改写了第一句话,以便在人们只想单独阅读部分内容时尝试让它仍然有效。 JavaScript 中存在模板字符串do。在编译器为旧目标添加 polyfill 的地方,它仍然不会添加到本机对象 - 它内联更改,或者(更罕见地)添加一个特殊命名的函数。模板字符串不满足 String.format 的所有用例。
  • @YannDuran 关键字是“本地”。如果你放下他说的话的症结,然后说你是对的,也许你是对的,但这与他在说什么无关。我喜欢放风筝。我喜欢飞行……看到区别了吗?
【解决方案3】:

如果您的唯一目标是消除丑陋的字符串连接和无聊的字符串转换,您可以使用 TypeScript 的原生字符串插值

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

注意:

在赋值语句的右侧,分隔符既不是单引号也不是双引号,而是一个称为反引号或重音符号的特殊字符

TypeScript 编译器会将右侧的特殊文字转换为字符串连接表达式。换句话说,这种语法不依赖于 ECMAScript 6 的特性,而是一个原生的 TypeScript 特性。您生成的 javascript 代码仍然兼容。

【讨论】:

  • 直到我看到你关于特殊刻度线的注释并意识到我做错了什么之前,我无法让字符串插值工作最长时间。
【解决方案4】:

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

NPM: 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;
    }
}

编辑:

我扩展了该类并在 github 上创建了一个存储库。如果您能帮助改进它,那就太好了!

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

或下载 npm 包

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

【讨论】:

  • 任何笨拙或小提琴?
  • 干得好,已经在使用你的包,几乎没有修改。
  • 干得好,这是我需要的一切的一站式商店。但是,这只与 webpack 2.2.0 兼容,我使用的是 3.3.0。
【解决方案5】:

作为达到相同目的的解决方法,您可以使用sprintf-js 库和types

我是从另一个 SO answer 那里得到的。

【讨论】:

    【解决方案6】:

    我是这样解决的;

    1.创建函数

    export function FormatString(str: string, ...val: string[]) {
      for (let index = 0; index < val.length; index++) {
        str = str.replace(`{${index}}`, val[index]);
      }
      return str;
    }
    

    2.像下面这样使用它;

    FormatString("{0} is {1} {2}", "This", "formatting", "hack");
    

    【讨论】:

    • 好的,但如果您想在字符串的多个位置重用相同的值,它将不起作用。你不能这样做例如:FormatString("{0} is happy because {0} solved his problem", "jeremy"); 第二个占位符将被省略。
    【解决方案7】:

    我正在使用 TypeScript 版本 3.6,我可以这样做:

    let templateStr = 'This is an {0} for {1} purpose';
    
    const finalStr = templateStr.format('example', 'format'); // This is an example for format purpose
    

    【讨论】:

    • 怎么样?我在 TS > 4 中得到 Property 'format' does not exist on type 'string'.
    【解决方案8】:

    如果你使用的是 NodeJS,你可以使用内置的 util 函数:

    import * as util from "util";
    util.format('My string: %s', 'foo');
    

    文档可以在这里找到: https://nodejs.org/api/util.html#util_util_format_format_args

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-08
      • 1970-01-01
      • 2018-11-08
      相关资源
      最近更新 更多