TypeScript:标记的模板文字显示错误

问题描述 投票:0回答:5

我正在尝试将 ES5 的标记模板文字与打字稿一起使用,但打字稿似乎没有完全支持它。我有以下代码。

class TemplateLiterals { 
    age: number = 24;
    name: 'Luke Skywalker'
    private tag(strings: string[], personExp, ageExp) :string{
        var str0 = strings[0]; // "that "
        var str1 = strings[1]; // " is a "
        var ageStr;
        if (ageExp > 99) {
            ageStr = 'centenarian';
        } else {
            ageStr = 'youngster';
        }
        return str0 + personExp + str1 + ageStr;
    }
    toString() {
        return this.tag `that ${ this.name } is a ${ this.age }`;
    }
}

toString
方法中,打字稿向我显示以下错误。

Argument of type 'TemplateStringsArray' is not assignable to parameter of type 'string[]'.
Property 'push' is missing in type 'TemplateStringsArray'.

我不知道为什么它会向我显示此错误。根据 mozilla 的文档“标签函数的第一个参数包含一个字符串值数组。”所以它应该接受字符串数组。但实际的期望是

TemplateStringsArray
。不确定如何以及何时定义
interface
TemplateSringsArray
。目前我正在使用
TemplateSringsArray
类型来避免此错误。谁能解释一下发生了什么。谢谢。这里是游乐场

javascript typescript template-literals
5个回答
12
投票

经过更多探索,我终于在更改日志中找到了解释。希望它能帮助某人。它说

ES2015 标记模板总是向其标记传递一个不可变的类似数组 具有名为 raw 的属性(也是不可变的)的对象。 TypeScript 将此对象命名为 TemplateStringsArray。

方便的是,TemplateStringsArray 可以分配给一个数组, 所以用户可能利用这一点来使用较短的类型 对于他们的标签参数:

function myTemplateTag(strs: string[]) {
    // ... 
} 

但是,在 TypeScript 2.0 中,该语言现在支持 readonly 修饰符和 可以表示这些对象是不可变的。作为 结果,TemplateStringsArray 也被设为不可变的,并且是不可变的 可以更长地分配给 string[]。

推荐:

明确使用

TemplateStringsArray
(或使用
ReadonlyArray<string>
)。


2
投票

我也找不到任何有关

TemplateStringsArray
的文档 - 但如果您只是通过将参数更改为
TemplateStringsArray
而不是
string[]
来忽略错误(并修复名称成员的错误),它似乎可以正常工作

class TemplateLiterals { 
    age: number = 24;
    name: string = 'Luke Skywalker'
    private tag(strings: TemplateStringsArray, personExp, ageExp) :string{
        var str0 = strings[0]; // "that "
        var str1 = strings[1]; // " is a "
        var ageStr;
        if (ageExp > 99) {
            ageStr = 'centenarian';
        } else {
            ageStr = 'youngster';
        }
        return str0 + personExp + str1 + ageStr;
    }
    toString() {
        return this.tag `that ${ this.name } is a ${ this.age }`;
    }
}

var luke: TemplateLiterals = new TemplateLiterals()
console.log(luke.toString())

1
投票

上述答案对我不起作用,也许要求现在已经改变(2021 年 12 月)。

但是我能够使用

ReadonlyArray<string>
而不是
string[]
解决我的问题。

这是我的示例函数,以防对某人有帮助。

function myTemplateTag(strs: ReadonlyArray<string>) {
  // Do something.
} 

0
投票

我对 Angular 的

$localize
函数也有同样的问题。我的问题是我用错了方法:

// ERROR:
const translated = $localize(`Something to translate!`);
// WORKS, remove the parentheses:
const translated = $localize`Something to translate!`;

希望能节省一些时间:D


0
投票

这就是当今 TypeScript 中简单模板评估的工作原理:

// Simple template-tag evaluator:
function _E(a: TemplateStringsArray, ...args:Array<any>): string {
    return a.map((b, i) => b + (i < args.length ? args[i] ?? '' : '')).join('');
}

测试:

const first = 'one';
const second = null; // to be skipped
const third = 123;

console.log(_E`${first}-${second}-${third}`);
//=> one--123
© www.soinside.com 2019 - 2024. All rights reserved.