Preserve enum computed property names in declarations - #4852
Preserve enum computed property names in declarations#4852Jake Bailey (jakebailey) wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Preserves enum member identity when serializing computed property names into declaration types.
Changes:
- Emits accessible enum members as computed property names.
- Adds string and numeric enum regression coverage.
- Updates local and accepted submodule baselines.
Reviewed changes
Copilot reviewed 42 out of 42 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
internal/checker/nodebuilderimpl.go |
Adds enum-aware property-name serialization. |
testdata/tests/cases/compiler/enumComputedPropertyDeclarationEmit.ts |
Adds regression cases. |
testdata/submoduleAccepted.txt |
Registers intentional baseline divergences. |
testdata/baselines/reference/compiler/enumComputedPropertyDeclarationEmit.js |
Records declaration emit. |
testdata/baselines/reference/compiler/enumComputedPropertyDeclarationEmit.types |
Records inferred types. |
testdata/baselines/reference/compiler/enumComputedPropertyDeclarationEmit.symbols |
Records symbol bindings. |
testdata/baselines/reference/submoduleAccepted/compiler/declarationEmitComputedNameConstEnumAlias.js.diff |
Accepts declaration delta. |
testdata/baselines/reference/submoduleAccepted/compiler/declarationEmitComputedNameConstEnumAlias.types.diff |
Accepts type delta. |
testdata/baselines/reference/submoduleAccepted/compiler/declarationEmitComputedPropertyNameEnum1.types.diff |
Accepts type delta. |
testdata/baselines/reference/submoduleAccepted/compiler/declarationEmitStringEnumUsedInNonlocalSpread.types.diff |
Accepts spread type delta. |
testdata/baselines/reference/submoduleAccepted/compiler/duplicateObjectLiteralProperty_computedName2.types.diff |
Accepts computed-name delta. |
testdata/baselines/reference/submoduleAccepted/compiler/duplicateObjectLiteralProperty_computedName3.types.diff |
Accepts imported-name delta. |
testdata/baselines/reference/submoduleAccepted/compiler/isolatedDeclarationErrorsObjects.types.diff |
Accepts isolated-declaration delta. |
testdata/baselines/reference/submoduleAccepted/compiler/objectLiteralEnumPropertyNames.types.diff |
Accepts enum property types. |
testdata/baselines/reference/submoduleAccepted/compiler/reducibleIndexedAccessTypes.types.diff |
Accepts indexed-access delta. |
testdata/baselines/reference/submoduleAccepted/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty11.types.diff |
Accepts numeric-enum delta. |
testdata/baselines/reference/submoduleAccepted/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty12.types.diff |
Accepts string-enum delta. |
testdata/baselines/reference/submoduleAccepted/conformance/computedPropertyNames47_ES5(target=es2015).types.diff |
Accepts ES5 conformance delta. |
testdata/baselines/reference/submoduleAccepted/conformance/computedPropertyNames47_ES6.types.diff |
Accepts ES6 conformance delta. |
testdata/baselines/reference/submoduleAccepted/conformance/computedPropertyNames48_ES5(target=es2015).types.diff |
Accepts ES5 conformance delta. |
testdata/baselines/reference/submoduleAccepted/conformance/computedPropertyNames48_ES6.types.diff |
Accepts ES6 conformance delta. |
testdata/baselines/reference/submoduleAccepted/conformance/computedPropertyNames7_ES5(target=es2015).types.diff |
Accepts ES5 enum-name delta. |
testdata/baselines/reference/submoduleAccepted/conformance/computedPropertyNames7_ES6.types.diff |
Accepts ES6 enum-name delta. |
testdata/baselines/reference/submoduleAccepted/conformance/destructuringObjectBindingPatternAndAssignment7(target=esnext).types.diff |
Accepts destructuring delta. |
testdata/baselines/reference/submodule/compiler/declarationEmitComputedNameConstEnumAlias.js |
Updates declaration baseline. |
testdata/baselines/reference/submodule/compiler/declarationEmitComputedNameConstEnumAlias.types |
Updates type baseline. |
testdata/baselines/reference/submodule/compiler/declarationEmitComputedPropertyNameEnum1.types |
Updates type baseline. |
testdata/baselines/reference/submodule/compiler/declarationEmitStringEnumUsedInNonlocalSpread.types |
Updates spread baseline. |
testdata/baselines/reference/submodule/compiler/duplicateObjectLiteralProperty_computedName2.types |
Updates computed-name baseline. |
testdata/baselines/reference/submodule/compiler/duplicateObjectLiteralProperty_computedName3.types |
Updates imported-name baseline. |
testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsObjects.types |
Updates isolated-declaration baseline. |
testdata/baselines/reference/submodule/compiler/objectLiteralEnumPropertyNames.types |
Updates enum property baseline. |
testdata/baselines/reference/submodule/compiler/reducibleIndexedAccessTypes.types |
Updates indexed-access baseline. |
testdata/baselines/reference/submodule/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty11.types |
Updates numeric-enum baseline. |
testdata/baselines/reference/submodule/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty12.types |
Updates string-enum baseline. |
testdata/baselines/reference/submodule/conformance/computedPropertyNames47_ES5(target=es2015).types |
Updates ES5 conformance baseline. |
testdata/baselines/reference/submodule/conformance/computedPropertyNames47_ES6.types |
Updates ES6 conformance baseline. |
testdata/baselines/reference/submodule/conformance/computedPropertyNames48_ES5(target=es2015).types |
Updates ES5 conformance baseline. |
testdata/baselines/reference/submodule/conformance/computedPropertyNames48_ES6.types |
Updates ES6 conformance baseline. |
testdata/baselines/reference/submodule/conformance/computedPropertyNames7_ES5(target=es2015).types |
Updates ES5 enum-name baseline. |
testdata/baselines/reference/submodule/conformance/computedPropertyNames7_ES6.types |
Updates ES6 enum-name baseline. |
testdata/baselines/reference/submodule/conformance/destructuringObjectBindingPatternAndAssignment7(target=esnext).types |
Updates destructuring baseline. |
Suppressed comments (1)
internal/checker/nodebuilderimpl.go:2473
- This predicate is both unsafe for a nil context and too narrow for qualified enums. With a nil enclosing declaration (used by inlay hints),
symbolToExpressionreceives only the member symbol and prints[A]instead of[E.A]; conversely, an enum nameable only asN.Ehas no direct accessible chain and is unnecessarily inlined. Require a real context (or deliberately fall back to the literal) and use the container-aware value-symbol accessibility path so qualified enum chains are accepted.
if enumEnclosingDeclaration == nil ||
len(b.ch.getAccessibleSymbolChain(enumSymbol, enumEnclosingDeclaration, ast.SymbolFlagsValue, false)) > 0 {
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
| enumEnclosingDeclaration := enclosingDeclaration | ||
| if b.ctx.enclosingFile != nil { | ||
| enumEnclosingDeclaration = b.ctx.enclosingFile.AsNode() | ||
| } |
Wesley Wigham (weswigham)
left a comment
There was a problem hiding this comment.
I've known about this for awhile - I was hoping we'd move this way after the changes for ID to preserve computed names more often.
The only thing is that while this makes the immediate cases better (obviously) by serializing as a computed name when the name type of a property is enum-y, we still compare enum and same-string-non-enum property names identically, so you can still lose key enum-yness through aliasing (eg, NonEnumKeys | EnumKeys may simplify to NonEnumKeys and now your remapping over it that prints an anonymous type loses it's key enum-y-ness) - a notable hole in the typesystem that this fix kinda glosses over without fixing, but maybe that's OK. We've had this issue ever since we made keyof track enums instead of underlying literals, but never really settled on a way we wanted to close the hole.
| enumSymbol = nameType.symbol | ||
| } | ||
| if enumEnclosingDeclaration == nil || | ||
| len(b.ch.getAccessibleSymbolChain(enumSymbol, enumEnclosingDeclaration, ast.SymbolFlagsValue, false)) > 0 { |
There was a problem hiding this comment.
Actually, rather than checking chain length (what?) this should just be IsSymbolAccessible, no?
There was a problem hiding this comment.
This PR was of course a first copilot attempt after talking to Chris on discord, I hadn't actually reviewed it quite yet; will go fix that
There was a problem hiding this comment.
embarassing as copilot memory is now disabled by default and it decides to randomly comment :<
Fixes #4850
This is a bug even in Strada; inlining the value means it's no longer of the enum type and things break.
See the second commit and how it drops the dts error.