Skip to content

Commit 10c4c32

Browse files
committed
fix: allow enum member references with non-identifier names as computed property names in type literals
Fixes #25083 Previously, using an enum member with a non-identifier name (like '3x14') as a computed property name in a type literal would incorrectly produce an error: 'A computed property name in a type literal must refer to an expression whose type is a literal type or a unique symbol type.' The fix updates checkGrammarForInvalidDynamicName to also allow element access expressions where: 1. The argument expression is a string or number literal 2. The expression being accessed is an entity name expression (like Type in Type['3x14']) This enables patterns like: enum Type { '3x14' = '3x14' } type TypeMap = { [Type['3x14']]: any } // Now works!
1 parent 77ddb5b commit 10c4c32

2 files changed

Lines changed: 30 additions & 2 deletions

File tree

src/compiler/checker.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52971,8 +52971,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
5297152971

5297252972
function checkGrammarForInvalidDynamicName(node: DeclarationName, message: DiagnosticMessage) {
5297352973
// 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
52974-
if (isNonBindableDynamicName(node) && !isEntityNameExpression(isElementAccessExpression(node) ? skipParentheses(node.argumentExpression) : (node as ComputedPropertyName).expression)) {
52975-
return grammarErrorOnNode(node, message);
52974+
if (isNonBindableDynamicName(node)) {
52975+
// Allow element access expressions with string/number literal arguments on entity name expressions
52976+
// This enables enum member references like `Type['3x14']` to be used as computed property names
52977+
if (isElementAccessExpression(node)) {
52978+
if (isStringOrNumberLiteralExpression(node.argumentExpression) && isEntityNameExpression(node.expression)) {
52979+
return;
52980+
}
52981+
}
52982+
if (!isEntityNameExpression(isElementAccessExpression(node) ? skipParentheses(node.argumentExpression) : (node as ComputedPropertyName).expression)) {
52983+
return grammarErrorOnNode(node, message);
52984+
}
5297652985
}
5297752986
}
5297852987

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// Repro from #25083
5+
6+
enum Type {
7+
Foo = 'foo',
8+
'3x14' = '3x14'
9+
}
10+
11+
type TypeMap = {
12+
[Type.Foo]: any
13+
[Type['3x14']]: any
14+
}
15+
16+
const x: TypeMap = {
17+
[Type.Foo]: 1,
18+
[Type['3x14']]: 2
19+
};

0 commit comments

Comments
 (0)