🔎 Search Terms
In processTaggedTemplateExpression the code checks whether the tagged template expression using the hasInvalidEscape function. This was done in #12700 to support a new feature in tagged template literals allowing for invalid escape sequences.
Unfortunately, the function was written in a way that relies on implicit from number -> boolean instead of masking the templateFlags field:
/** @internal */
export function hasInvalidEscape(template: TemplateLiteral): boolean {
return template && !!(isNoSubstitutionTemplateLiteral(template)
? template.templateFlags
: (template.head.templateFlags || some(template.templateSpans, span => !!span.literal.templateFlags)));
}
This means the code assumes any template literal with non-zero flags contains an invalid escape. While this was true in the past, new flags were introduced in 5.1 breaking the logic of the code.
Now all tagged templates containing unicode escape sequences now get transpiled when they don't need to, causing a code size increase.
🕗 Version & Regression Information
This changed between versions 5.0.4 and 5.1.6
v5.0.4: https://www.typescriptlang.org/play?target=3&jsx=0&module=1&ts=5.0.4#code/GYVwdgxgLglg9mABMOcA8AVAfACgIYBciGAlAN4BOAplCBUngNwC+AUBAgM5SJ6IC8yVAAMAOiAAMUicMbsuPAEYChcYXllA
v5.1.6: https://www.typescriptlang.org/play?target=3&jsx=0&module=1&ts=5.1.6#code/GYVwdgxgLglg9mABMOcA8AVAfACgIYBciGAlAN4BOAplCBUngNwC+AUBAgM5SJ6IC8yVAAMAOiAAMUicMbsuPAEYChcYXllA
⏯ Playground Link
https://www.typescriptlang.org/play?target=3&jsx=0&module=1&ts=5.1.6#code/GYVwdgxgLglg9mABMOcA8AVAfACgIYBciGAlAN4BOAplCBUngNwC+AUBAgM5SJ6IC8yVAAMAOiAAMUicMbsuPAEYChcYXllA
💻 Code
function foo<T>(a: T){return a;}
const a = foo`\u0000`;
const b = foo`a`;
🙁 Actual behavior
"use strict";
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
};
function foo(a) { return a; }
const a = foo(__makeTemplateObject(["\0"], ["\\u0000"]));
const b = foo `a`;
🙂 Expected behavior
"use strict";
function foo(a) { return a; }
const a = foo `\u0000`;
const b = foo `a`;
🔎 Search Terms
In
processTaggedTemplateExpressionthe code checks whether the tagged template expression using thehasInvalidEscapefunction. This was done in #12700 to support a new feature in tagged template literals allowing for invalid escape sequences.Unfortunately, the function was written in a way that relies on implicit from
number->booleaninstead of masking thetemplateFlagsfield:This means the code assumes any template literal with non-zero flags contains an invalid escape. While this was true in the past, new flags were introduced in 5.1 breaking the logic of the code.
Now all tagged templates containing unicode escape sequences now get transpiled when they don't need to, causing a code size increase.
🕗 Version & Regression Information
This changed between versions 5.0.4 and 5.1.6
v5.0.4: https://www.typescriptlang.org/play?target=3&jsx=0&module=1&ts=5.0.4#code/GYVwdgxgLglg9mABMOcA8AVAfACgIYBciGAlAN4BOAplCBUngNwC+AUBAgM5SJ6IC8yVAAMAOiAAMUicMbsuPAEYChcYXllA
v5.1.6: https://www.typescriptlang.org/play?target=3&jsx=0&module=1&ts=5.1.6#code/GYVwdgxgLglg9mABMOcA8AVAfACgIYBciGAlAN4BOAplCBUngNwC+AUBAgM5SJ6IC8yVAAMAOiAAMUicMbsuPAEYChcYXllA
⏯ Playground Link
https://www.typescriptlang.org/play?target=3&jsx=0&module=1&ts=5.1.6#code/GYVwdgxgLglg9mABMOcA8AVAfACgIYBciGAlAN4BOAplCBUngNwC+AUBAgM5SJ6IC8yVAAMAOiAAMUicMbsuPAEYChcYXllA
💻 Code
🙁 Actual behavior
🙂 Expected behavior