Ensure enum members syntactically determinable to be strings do not get reverse mappings (#57686)

Co-authored-by: frigus02 <3579251+frigus02@users.noreply.github.com>
Co-authored-by: Jan Kühle <jkuehle90@gmail.com>
This commit is contained in:
Andrew Branch
2024-03-13 13:11:02 -07:00
committed by GitHub
parent ac8eb2c993
commit f9ef9439bd
13 changed files with 203 additions and 1 deletions

View File

@@ -122,6 +122,7 @@ import {
isSimpleInlineableExpression,
isSourceFile,
isStatement,
isSyntacticallyString,
isTemplateLiteral,
isTryStatement,
JsxOpeningElement,
@@ -1922,7 +1923,7 @@ export function transformTypeScript(context: TransformationContext) {
),
valueExpression,
);
const outerAssignment = valueExpression.kind === SyntaxKind.StringLiteral ?
const outerAssignment = isSyntacticallyString(valueExpression) ?
innerAssignment :
factory.createAssignment(
factory.createElementAccessExpression(

View File

@@ -10638,3 +10638,22 @@ export function replaceFirstStar(s: string, replacement: string): string {
export function getNameFromImportAttribute(node: ImportAttribute) {
return isIdentifier(node.name) ? node.name.escapedText : escapeLeadingUnderscores(node.name.text);
}
/** @internal */
export function isSyntacticallyString(expr: Expression): boolean {
expr = skipOuterExpressions(expr);
switch (expr.kind) {
case SyntaxKind.BinaryExpression:
const left = (expr as BinaryExpression).left;
const right = (expr as BinaryExpression).right;
return (
(expr as BinaryExpression).operatorToken.kind === SyntaxKind.PlusToken &&
(isSyntacticallyString(left) || isSyntacticallyString(right))
);
case SyntaxKind.TemplateExpression:
case SyntaxKind.StringLiteral:
case SyntaxKind.NoSubstitutionTemplateLiteral:
return true;
}
return false;
}

View File

@@ -673,4 +673,13 @@ export * as alias from './file';`,
options: { compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ESNext } },
},
);
transpilesCorrectly(
"Syntactically string but non-evaluatable enum members do not get reverse mapping",
// eslint-disable-next-line no-template-curly-in-string
"import { BAR } from './bar'; enum Foo { A = `${BAR}` }",
{
options: { compilerOptions: { target: ts.ScriptTarget.ESNext } },
},
);
});