Skip to content

Enums as union types aren't compatible with strings (5.0) #53304

Closed

Description

@Ayc0

Bug Report

In https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#all-enums-are-union-enums, it mentions that enums can be used as union types, allowing to do this:

TypeScript Play

image

The issue is that this seems to only work with numbers, but not with other types like strings. If we take the exact same code but replace all numbers with strings, we have this:

Type '"42"' is not assignable to type 'E'. (2322)

TypeScript Play

image

🔎 Search Terms

enum, union, string

🕗 Version & Regression Information

This new feature was introduced in the v5.0.0, and I tested it locally in the v5.0.2 and in the sandbox with the version 5.1.0-dev.20230316.

⏯ Playground Link

Playground link with relevant code

💻 Code

enum E {
    A = '42',
}

export let fine: E = '42'; // fails but should work
//         ^
export let oops: E = '43'; // fails as expected

// ====

enum F {
    Foo = '10',
    Bar = '20',
}

function takeValue(e: F) {}
takeValue(F.Foo); // works
takeValue('10'); // fails but should work
//        ^
takeValue('123'); // fails as expected

🙁 Actual behavior

The error Type '"42"' is not assignable to type 'E'. (2322) is sent by TS for the code let fine: E = '42';.

🙂 Expected behavior

This shouldn’t behave differently from numbers, so writing let fine: E = '42'; could be allowed by TS

Activity

  1. changed the title [-]Enums as union types aren't compatible with strings[/-] [+]Enums as union types aren't compatible with strings (5.0)[/+] on Mar 17, 2023
  2. fatcerberus commented on Mar 17, 2023

    @fatcerberus

    AFAIK string enums are intentionally stricter than numeric ones, so this is probably by design.

  3. notaphplover commented on Mar 17, 2023

    @notaphplover

    It's doesn't seem to be a bug. Consider this message from the lead architect of TypeScript.

  4. Ayc0 commented on Mar 17, 2023

    @Ayc0
    Author

    Thanks for the information! 🙏

    If that's expected, should the release note be updated to highlight the fact that this only works for numbers and not for all types?

    It mentions that enums started as "a set of numeric constants with the same type" and that in the example "E.Foo and E.Bar (...) were pretty much just numbers".
    But it doesn’t explicitly say that the union feature can only work with numbers (specially when it mentions "Enum literal types gave each enum member its own type", and later "That means that all enums can now be narrowed and have their members referenced as types as well", which can lead to a bit of confusion).

  5. Ayc0 commented on Mar 17, 2023

    @Ayc0
    Author

    I think you’re right notaphplover, this comment was a reply of a question in the PR exactly about the behavior mentioned by this issue. So it doesn’t seem to be a bug.

    I’ll close this as completed.

  6. devlopersabbir commented on Jul 29, 2024

    @devlopersabbir

    Here is a simple way to do that.

    Here the example of how to convert a Typescript enum to a union type

    export enum PaymentSystemEnum {
      APPLE = 'APPLE',
      GOOGLE = 'GOOGLE'
    }

    And it’s pretty easy

    type = `${PaymentSystemEnum}`; // "APPLE" | "GOOGLE"

    Reference Link

  7. locked as resolved and limited conversation to collaborators on Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions