I am trying to use tagged template literal of ES5 with typescript but it seems like type script does not have full support for it. I have following piece of code.
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 }`;
}
}
In toString
method, typescript is showing me following error.
Argument of type 'TemplateStringsArray' is not assignable to parameter of type 'string[]'.
Property 'push' is missing in type 'TemplateStringsArray'.
I don't know why it's showing me this error. As per the mozilla's doc "The first argument of a tag function contains an array of string values." So it should accept the array of string. But the actual expectation is TemplateStringsArray
. not sure how and when the interface
TemplateSringsArray
is being defined. Currently I am using TemplateSringsArray
type to avoid this error. Can anyone please explain whats happening. Thanks. Here's the playground.
After exploring more, I finally found explanations in the change log. Hope it will help someone. It says
ES2015 tagged templates always pass their tag an immutable array-like object that has a property called raw (which is also immutable). TypeScript names this object the TemplateStringsArray.
Conveniently, TemplateStringsArray was assignable to an Array, so it's possible users took advantage of this to use a shorter type for their tag parameters:
function myTemplateTag(strs: string[]) {
// ...
}
However, in TypeScript 2.0, the language now supports the readonly modifier and can express that these objects are immutable. As a result, TemplateStringsArray has also been made immutable, and is no longer assignable to string[].
Recommendation:
Use TemplateStringsArray
explicitly (or use ReadonlyArray<string>
).