Skip to content

Conversation

@tt-a1i
Copy link
Contributor

@tt-a1itt-a1i commented Dec 12, 2025

Summary

This PR fixes#25083 where enum keys accessed with bracket notation (e.g., Type['3x14']) were not recognized as valid computed property names in type literals, even when they resolved to literal types.

The problem

enumType{Foo='foo','3x14'='3x14'// Non-identifier enum key}typeTypeMap={[Type.Foo]: any;// ✅ Works[Type['3x14']]: any;// ❌ Error: TS1170 - but should work!}

The error occurred because isLateBindableAST only recognized EntityNameExpression (Identifier or PropertyAccessExpression) but not ElementAccessExpression with literal keys.

The fix

Introduced isLateBindableAccessExpression, a helper function that recursively validates access expressions:

  • Identifiers
  • PropertyAccessExpression where the name is an Identifier (not PrivateIdentifier) and the base is valid
  • ElementAccessExpression where the argument is a string/numeric literal (after skipping parentheses) and the base is valid
  • Parenthesized expressions are skipped via skipParentheses

This supports:

  • Pure property access: obj.a.b.c
  • Pure element access: obj['a']['b']['c']
  • Mixed chains: obj.a['b'].c['d']
  • Parenthesized expressions: (obj.a)['b']
  • Parenthesized keys: obj[('a')]

Also updated checkGrammarForInvalidDynamicName to use the new helper (it handles skipParentheses internally now).

Testing

Added test case enumKeysAsComputedPropertiesWithBracketNotation.ts covering:

  • Enum keys with bracket notation (Type['3x14'])
  • Bracket notation with identifier keys (Type['Foo'])
  • Nested element access (obj['a']['b'])
  • Mixed chains (obj['a'].b, obj.a['b'])
  • Complex mixed chains (deep.a['b'].c['d'])
  • Parenthesized expressions ((obj.a).b, (obj['a']).b)
  • Parenthesized keys (obj[('a')], deep[('a')][('b')].c['d'])

Baseline changes

enumKeysAsComputedPropertiesWithBracketNotation.*

  • New test file baselines for the fix

isolatedDeclarationLazySymbols.errors.txt

  • Removed false positive error for Direction['Up'] in [Direction['Up']]: number
  • This was previously incorrectly flagged as TS1170 because Direction['Up'] wasn't recognized as a valid late-bindable name
  • Now correctly allows this pattern since it resolves to a literal type "UP"

isolatedDeclarationLazySymbols.types

  • The type for [Direction['Up']] now correctly resolves to "UP" instead of showing error
  • This reflects the fix allowing element access on enums to be used as computed property names

All 99,161 tests pass.

This fixesmicrosoft#25083 where enum keys accessed with bracket notation (e.g., `Type['3x14']`) were not recognized as valid computed property names in type literals, even when they resolved to literal types. The fix extends `isLateBindableAST` to recognize `ElementAccessExpression` with string or numeric literal keys as valid late-bindable expressions, similar to how `PropertyAccessExpression` is already handled. This also updates `checkGrammarForInvalidDynamicName` to allow such expressions as computed property names.
@github-project-automationgithub-project-automationbot moved this to Not started in PR BacklogDec 12, 2025
@typescript-bottypescript-bot added the For Backlog Bug PRs that fix a backlog bug label Dec 12, 2025
@tt-a1i
Copy link
ContributorAuthor

@microsoft-github-policy-service agree

- Rename isEntityNameOrElementAccessExpression to isLateBindableAccessExpression - Support mixed chains like obj.a['b'].c['d'] - Add skipParentheses handling for expressions like (obj.a)['b'] - Ensure PropertyAccessExpression name is Identifier (not PrivateIdentifier) - Add comprehensive test cases for mixed chains and parenthesized expressions
Support obj[('a')] by applying skipParentheses to argumentExpression before checking isStringOrNumericLiteralLike. Added test cases for parenthesized keys in element access.
- Fix declaration emit elide condition to recognize ElementAccessExpression as a valid late-bindable expression (declarations.ts:1026) - Update isolatedDeclarations check to accept late-bindable access expressions (declarations.ts:1019) - Add LateBindableAccessExpression type alias for clearer semantics - Extract isLateBindableAccessExpression to utilities.ts and remove duplicate implementation from checker.ts - Update getFirstIdentifier to support ElementAccessExpression chains - Update isEntityNameVisible and related APIs to accept ElementAccessExpression - Add test case with @declaration: true to verify computed properties are preserved in generated .d.ts files
- Add reference baselines for enumKeysExportScenario test - Fix getFirstIdentifier to skipParentheses when traversing access chains to handle cases like (obj.a)['b']
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

For Backlog BugPRs that fix a backlog bug

Projects

Status: Not started

Development

Successfully merging this pull request may close these issues.

Enum keys not accepted as computed properties if their name is not a valid identifier

2 participants

@tt-a1i@typescript-bot