Enums considered harmful

preview_player
Показать описание
TypeScript enums are not great. In almost all cases, I use an 'as const' with a sprinkling of type magic to express them.

Become a TypeScript Wizard with Matt's TypeScript Course:

Follow Matt on Twitter

Рекомендации по теме
Комментарии
Автор

Forgot to mention in the video, but union types are great alternative to const enums. Want your code to disappear at runtime? Don't need an object representation? Just use a union of strings:

type LogLevel = 'DEBUG' | 'WARNING' | 'ERROR';

mattpocockuk
Автор

Enums have worked great for me. Readability and robustness that they introduce outweigh the potential pitfalls IMO. In fact, I've never even run into problems discussed in the video myself

oleksandrfomin
Автор

I have to disagree.
After watching the video i feel like i prefer Enums the way they are in Typescript, than what you proposed.
Not that i have not messed it up once or twice before, but i think, as you said, i would really dislike allowing strings in places where i require an enum.
It's the reason i use the enums in the first place.
In most cases you are also not supposed to dereference enums, i would say.

object_name
Автор

Hey Matt, I like how you express yourself. Well-paced and with plenty of depth without getting long-winded. Awesome!

ThijmenCodes
Автор

The best thing about the content of this channel is that they're short, succinct but massively useful. Much better than watching a 60 minutes presentation

MrTruthAndFacts
Автор

Honestly the fact that enums aren't just structural is an advantage to me. The main point of using enums is that you use enums and not strings. String enums have the best behaviour out of all the options mentioned.

jandurek
Автор

My Typescript understanding has improved a lot since I started to watch your videos, Matt.
Thanks for that

artu-hnrq
Автор

2:25 I don't think this defeats the purpose of enums and in fact should be the recommended way of using enums since it mirrors the const object. I find you don't want to ever allow bare strings as values that as supposed to be mapped to a specific thing...makes refactoring much harder...and I also make it a rule not to look at compiled code and stick to the actual source.
I use enums like this:

enum LogLevelEnum {
debug = 'DEBUG',
warning = 'WARNING',
error = 'ERROR',
}

type LogKeys = keyof typeof LogLevelEnum;
type LogLevel = typeof LogLevelEnum[LogKeys];

let logLevel: LogLevel = LogLevelEnum.debug;

aduad
Автор

Thanks Matt,
I shared this video with multiple people already, I knew enums are problematic but didn't really know why, you did great job making me understand.

The way you plugged your payed course is perfectly done and I hope other from industry are taking notes.

markovujanic
Автор

If you'd like to allow the string representation of the enum you can do something similar

enum LogLevel {
DEBUG = 'DEBUG',
WARNING = 'WARNING',
ERROR = 'ERROR',
}

function log(message: string, level: LogLevel | `${LogLevel}`) {

}

log('Hello!', LogLevel.DEBUG); // Works
log('Hello!', 'DEBUG'); // Also works

duro
Автор

Gonna make a few dot points to try understand what youre saying -
1. Enums, when compiled, map in both direction. Meaning if you are treating it like an object, you will have extra key: value pairs that you need to expect.
2. Typescript cares about the Names of Enums. You cant use the Values of the enums in place of the name of the enum.
3. A neat alternative can be either Union Types or Const Object
4. Const Object together with ObjectValues type has the benefit of being able to use the Name or value of the item. Benefits of Enums naming without the above two issues.
5. Another Benefit is having the Object have a machine readable key, with a human readable representation of the key as the value.

Thanks for the tips! :)

tunoajohnson
Автор

I am using enums for my whole framework. They are perfectly fine

Joso
Автор

Your representation of how to achieve the same result as an enum at 7:11 was a little uncharitable imho, as you could have simply written:

```
enum LogLevel {
DEBUG = 'Debug',
WARNING = 'Warning',
ERROR = 'Error',
}

function log(message: string, level: LogLevel) {
console.log(`${level}: ${message}`);
}

log('Hey', LogLevel.DEBUG)
```

Which is almost identical to using a constant object literal. I've never had an issue with enums when the values are strings

benjidaniel
Автор

i have different opinions on TS enums:

1- i think (like you said) the enums are the best option for code refactoring, and a great solution for keeping values throughout your code base the same. (when you change the values in one place, they change in every place the enum is used, if you just pass arguments from an enum, but as just strings, you will need to change every place that value is used);

2- about the thing that you shouldn't be explicit when using enums, because it sort of defeats it's purpose, i 100% agree with that, but i also think being explicit is way better than implicit, because someone may change the order of variables (in a conflict from merging, for example) and change it's values, or is just too inexperienced and mess something up;

3- (and this is about everything in transpiled JS) about the way it is done in javascript when transpiled, i think if it performs great, do it's job without problems and will not be a problem for the developers and users in the future, it shouldn't be something you care that much about, because you will not see this code, what you see/code is TS, the JS is just runned by the engine.

josedallasta
Автор

commenting to support the channel. loving the content lately, hopefully more to come!

orlantquijada
Автор

Waiting for the next video "Don't use letters! They can be harmful"

pw
Автор

without the re-enacting of 'hey maccarena' by the hands: One of the better instructional videos on ts i have seen.

iterativeincremental
Автор

Actually you don't need different names for const asserted enums and their type. You can have "const LogLevel = { ... } as const;" and "type LogLevel = ObjectValues<typeof LogLevel>;" in the same file. That's basically how @prisma/client generates enums from the schema.

mahmutjomaa
Автор

Using POJO is always my preferred way to go now. Great video!

tomasburian
Автор

Enums have worked great for me. The readability and robustness that they introduce outweigh the potential pitfalls IMO. In fact, I've never even run into problems discussed in the video myself

jimmycat