diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0567712f11da3..296cdf2c3b4f9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -52971,8 +52971,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function checkGrammarForInvalidDynamicName(node: DeclarationName, message: DiagnosticMessage) { // Even non-bindable names are allowed as late-bound implied index signatures so long as the name is a simple `a.b.c` type name expression - if (isNonBindableDynamicName(node) && !isEntityNameExpression(isElementAccessExpression(node) ? skipParentheses(node.argumentExpression) : (node as ComputedPropertyName).expression)) { - return grammarErrorOnNode(node, message); + if (isNonBindableDynamicName(node)) { + // Allow element access expressions with string/number literal arguments on entity name expressions + // This enables enum member references like `Type['3x14']` to be used as computed property names + if (isElementAccessExpression(node)) { + if (isStringOrNumberLiteralExpression(node.argumentExpression) && isEntityNameExpression(node.expression)) { + return; + } + } + if (!isEntityNameExpression(isElementAccessExpression(node) ? skipParentheses(node.argumentExpression) : (node as ComputedPropertyName).expression)) { + return grammarErrorOnNode(node, message); + } } } diff --git a/tests/cases/compiler/enumComputedPropertyNameWithInvalidIdentifier.ts b/tests/cases/compiler/enumComputedPropertyNameWithInvalidIdentifier.ts new file mode 100644 index 0000000000000..156e4c832f37f --- /dev/null +++ b/tests/cases/compiler/enumComputedPropertyNameWithInvalidIdentifier.ts @@ -0,0 +1,19 @@ +// @strict: true +// @noEmit: true + +// Repro from #25083 + +enum Type { + Foo = 'foo', + '3x14' = '3x14' +} + +type TypeMap = { + [Type.Foo]: any + [Type['3x14']]: any +} + +const x: TypeMap = { + [Type.Foo]: 1, + [Type['3x14']]: 2 +};