Typescript: Enum number return type is not type safe

Created on 12 Feb 2020  路  4Comments  路  Source: microsoft/TypeScript

TypeScript Version: 3.8.0-dev.20200211


Search Terms:
Enum return type, enum strictly typing, enum type safety
Code

enum Hello{
  world
}

const sayHello = ():Hello => {
  return 2;
};
console.log(sayHello()); // 2

Expected behavior:
An exception/error that 2 is not one of the enum option
and that i should use the enum and not just a number value. Which in the programming world
is commonly known as Magic number

Actual behavior:
returns 2
Playground Link:
https://www.typescriptlang.org/play/?ssl=1&ssc=1&pln=8&pc=30#code/KYOwrgtgBAEsA28D2BvAsAKClA7kgTvACZQC8UAjJgL6aYDGSIAzgC5TMCGAnnIkmSgAKAJQAuPsjIA+KOixR8wVmHwgoAJgDcNHRkYsk8YADpkAcyFdeCZKJFaoAeieagA

Hackish workaround:

enum Hello{
  world = "1",
}

const sayHello = ():Hello => {
  return "2"; // <-- will give an error
};
console.log(sayHello()); // 2

But typescript should make our code more typesafe and give enums the power it should have in first place.

Duplicate

All 4 comments

Number enums are not really enums at all. It's "by design", even if many people don't agree.

They were originally meant to just be useful aliases for bitmasks.

[Edit]
See: https://github.com/microsoft/TypeScript/issues/32690

Enum numbers are by design meant to be not actually enums and string enums are by design actual enums?

I would just expect number enums to act the same as string enums

Hope you can help me out, it's giving different type restrictions depending on if the Enum is a number or string.

If many people feel the same then it's good to discuss about it

I think you would agree with me that the restrictions for string enums should also be reflected with number / default enums and will help the developer gain a more strictly typed environment

I don't like it, either. It is what it is, though.

But, yes, number and string enums have different behavior. Also, if you look at the JS emit for number and string enums, you'll see that they're also different.

It's worth noting that JS has no actual enum type. It's a TS concept. Just like namespace.


I just tell people to not use enums nowadays.

Just do something like,

const MyNumberEnum = {
  A : 123,
  B : 456,
} as const;
type MyNumberEnum = typeof MyNumberEnum[keyof typeof MyNumberEnum]

Or,

const MyStringEnum = {
  A : "a",
  B : "b",
} as const;
type MyStringEnum = typeof MyStringEnum[keyof typeof MyStringEnum]

It does make the emit uglier, though. In places, you'll see a union type, instead of MyNumberEnum

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RyanCavanaugh picture RyanCavanaugh  路  205Comments

blakeembrey picture blakeembrey  路  171Comments

xealot picture xealot  路  150Comments

metaweta picture metaweta  路  140Comments

tenry92 picture tenry92  路  146Comments