Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Ayc0 opened this issue Mar 17, 2023 · 5 comments
Closed

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

Ayc0 opened this issue Mar 17, 2023 · 5 comments

Comments

@Ayc0
Copy link

Ayc0 commented Mar 17, 2023

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

@Ayc0 Ayc0 changed the title Enums as union types aren't compatible with strings Enums as union types aren't compatible with strings (5.0) Mar 17, 2023
@fatcerberus
Copy link

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

@notaphplover
Copy link

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

@Ayc0
Copy link
Author

Ayc0 commented Mar 17, 2023

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).

@Ayc0
Copy link
Author

Ayc0 commented Mar 17, 2023

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.

@devlopersabbir
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants