Closed
Description
TypeScript Version: 2.4.1
Code
let previousStrings;
function test(strings, ...value) {
if (previousStrings !== undefined && previousStrings !== strings) {
window.alert('failure');
}
previousStrings = strings;
}
function go(n) {
return test`literal ${n}`;
}
Expected behavior:
According to the ECMAScript spec, every time a template tag is evaluated, the same strings object should be passed as the first argument:
Each TemplateLiteral in the program code of a realm is associated with a unique template object that is used in the evaluation of tagged Templates (12.2.9.6). The template objects are frozen and the same template object is used each time a specific tagged Template is evaluated.
https://tc39.github.io/ecma262/#sec-gettemplateobject
Actual behavior:
The above snippet compiles to:
var previousStrings;
function test(strings) {
var value = [];
for (var _i = 1; _i < arguments.length; _i++) {
value[_i - 1] = arguments[_i];
}
if (previousStrings !== undefined && previousStrings !== strings) {
window.alert('failure');
}
previousStrings = strings;
}
function go(n) {
return (_a = ["literal ", ""], _a.raw = ["literal ", ""], test(_a, n));
var _a;
}
You can see that _a
is going to have a new identity for each call of go().
FWIW, Babel compiles this correctly:
'use strict';
var _templateObject = _taggedTemplateLiteral(['literal ', ''], ['literal ', '']);
function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
var previousStrings = void 0;
function test(strings) {
if (previousStrings !== undefined && previousStrings !== strings) {
window.alert('failure');
}
previousStrings = strings;
}
function go(n) {
return test(_templateObject, n);
}
This is breaking lit-html when used in TypeScript: lit/lit#58