Skip to content

Allow enum keys accessed with bracket notation as computed properties#62892

Closed
tt-a1i wants to merge 5 commits intomicrosoft:mainfrom
tt-a1i:fix/enum-keys-computed-properties
Closed

Allow enum keys accessed with bracket notation as computed properties#62892
tt-a1i wants to merge 5 commits intomicrosoft:mainfrom
tt-a1i:fix/enum-keys-computed-properties

Conversation

@tt-a1i
Copy link
Contributor

@tt-a1i tt-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

enum Type {
  Foo = 'foo',
  '3x14' = '3x14'  // Non-identifier enum key
}

type TypeMap = {
  [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 fixes microsoft#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-automation github-project-automation bot moved this to Not started in PR Backlog Dec 12, 2025
@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Dec 12, 2025
@tt-a1i
Copy link
Contributor Author

tt-a1i commented Dec 12, 2025

@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']
@typescript-bot
Copy link
Collaborator

With 6.0 out as the final release vehicle for this codebase, we're closing all PRs that don't fit the merge criteria for post-6.0 patches. If you think this was a mistake and this PR fits the post-6.0 patch criteria, please post to the 6.0 iteration issue with details (specifically, which PR and which patch criteria it satisfies).

Next steps for PRs:

  • For crash bugfixes or language service improvements, PRs are currently accepted at the typescript-go repo
  • Changes to type system behavior should wait until after 7.0, at which point mainline TypeScript development will resume in this repository with the Go codebase
  • Library file updates (lib.d.ts etc) continue to live in this repo or the DOM Generator repo as appropriate

@github-project-automation github-project-automation bot moved this from Not started to Done in PR Backlog Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

For Backlog Bug PRs that fix a backlog bug

Projects

Status: Done

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