TypeScript:标记模板字面量显示错误。

12

我正在尝试在TypeScript中使用ES5的标记模板字面量,但似乎TypeScript对其支持不完整。以下是我的代码片段。

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方法中,TypeScript向我显示了以下错误。
Argument of type 'TemplateStringsArray' is not assignable to parameter of type 'string[]'.
Property 'push' is missing in type 'TemplateStringsArray'.

我不知道为什么会出现这个错误。根据 Mozilla 的文档,“标签函数的第一个参数包含字符串值的数组”。因此应该接受字符串数组。但实际期望是 TemplateStringsArray。不确定 interface TemplateSringsArray 是如何定义的,也不知道何时定义。目前我正在使用 TemplateStringsArray 类型来避免此错误。请问有人能解释一下发生了什么吗?谢谢。这里是playground

4个回答

11

在进一步探索后,我终于在更改日志中找到了解释。希望能对某人有所帮助。它说:

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

方便的是,TemplateStringsArray可以分配给一个Array,因此用户可以利用这一点来使用更短的类型作为他们的标记参数:

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

然而,在TypeScript 2.0中,语言现在支持readonly修饰符并且可以表示这些对象是不可变的。因此,TemplateStringsArray也已经被设置为不可变,并且不再可分配给string[]。

建议:

明确使用TemplateStringsArray(或使用ReadonlyArray<string>)。


1
只有在您对该函数具有控制权时,这才是有用的。 - AntonOfTheWoods

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

Currently I am using TemplateSringsArray type to avoid this error. - Hitesh Kumar

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接