Skip to content

Inconsistency between comment and implementation for enum computed property names #62649

@magic-akari

Description

@magic-akari

🔎 Search Terms

  • enum
  • computed

🕗 Version & Regression Information

  • This changed between versions ______ and _______
  • This changed in commit or PR _______
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
  • I was unable to test this on prior versions because _______

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/KYOwrgtgBAwgEgQQEpQN4CgpagMwPZ5QC8UAjADTZVQD0NUgoORRLADmYANgIYBOUokKBGAQARsB7pM2AOQAdAC4ziUAAwAPVQE5K2OoygBlBTwCWIVlA6mFErh2lYARHJBOVG1Ql1Z9TY2YWVjZ2Do5QANryAG4yALoemgBCun5GJuaW1rY89lAA7jYAFuZQorkAxgDWwAoAzuERLjhOCSSeMKn0-hlB2aEFxaXlXNW1DVQRAAZyPFNtapoAIl0GACoiAA7ctsE5eQAUIIR1YKJ1CjZgl3ggAJSDCiUgZZU19egAvlIC0GsAooY1mhwlMALRTDw+agwqj6QAy5FANhBtlxdv1chwoHhrnVTAATYCvUbvOpQMFQf48Hh4PhrQwAJgAzAA2AAsjScXHcAGooE5RK0VBRYXp6IikuZeABPfjqTY8YB1PG3cmU6m0pGGUikdmNKZFYAcDiEAAkqCc+VpHHxTk+8xUDMoCKRWx2RIxeUKTygp3OlwU11MqopVJpdO1uo5nyAA

💻 Code

enum CHAR {
    foo = 1,        // ✅ Regular enum member

    '\t' = 0x09,    // ✅ String literal
    "\n" = 0x0A,    // ✅ String literal

    ['\v'] = 0x0B,  // ✅ String literal within brackets
    ["\f"] = 0x0C,  // ✅ String literal within brackets
    [`\r`] = 0x0D,  // ✅ Template literal (no substitution) within brackets
}

enum TEST {
    `-` = 0,                  // ❌ Template literal outside brackets - Error TS2364
    ["a" + "b"] = 1,          // ❌ Binary expression - Error TS1164
    [`hello ${"world"}`] = 2, // ❌ Template literal with substitution - Error TS1164
}

🙁 Actual behavior

The computed enum member is accepted by TypeScript

🙂 Expected behavior

Not sure

Additional information about the issue

Summary

While investigating how to properly handle enum computed property names in SWC (see swc-project/swc#11160), I noticed an inconsistency between the code comment and the actual implementation in TypeScript's compiler.

The Issue

In types.ts:3601-3608, the comment states:

export interface EnumMember extends NamedDeclaration, JSDocContainer {
    readonly kind: SyntaxKind.EnumMember;
    readonly parent: EnumDeclaration;
    // This does include ComputedPropertyName, but the parser will give an error
    // if it parses a ComputedPropertyName in an EnumMember
    readonly name: PropertyName;  // PropertyName includes ComputedPropertyName
    readonly initializer?: Expression;
}

However, the actual behavior differs from this comment:

  1. The parser does NOT emit errors for computed property names with literal expressions like ["\t"] or [`hello`]
  2. Validation actually happens in the type checker (checker.ts:47808), which only rejects non-literal computed expressions

Example

This code is accepted by TypeScript:

enum CHAR {
    ['\v'] = 0x0B,  // ✅ String literal within brackets - accepted
    ["\f"] = 0x0C,  // ✅ String literal within brackets - accepted
    [`\r`] = 0x0D,  // ✅ Template literal (no substitution) within brackets - accepted
}

While this is rejected:

enum TEST {
    ["a" + "b"] = 1,          // ❌ Binary expression - Error TS1164
    [`hello ${"world"}`] = 2, // ❌ Template literal with substitution - Error TS1164
}

Question

There's a clear inconsistency between the comment and the implementation. Could you clarify which one reflects the intended design?

Understanding the intended behavior would help us implement the correct handling in SWC.

Thank you for your time!

Metadata

Metadata

Assignees

Labels

Needs InvestigationThis issue needs a team member to investigate its status.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions