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