-
-
Notifications
You must be signed in to change notification settings - Fork 6.6k
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
Remove all TypeScript enums and forbid them in ESLint #4580
Remove all TypeScript enums and forbid them in ESLint #4580
Conversation
Replace the TypeScript `enum {a = "a", b = "b"}` types with TypeScript's literal types (e.g. `"a" | "b"`). This is because TypeScript enums are [_not_ a type-level addition to JavaScript][1], and even the official TypeScript docs say to be careful when using. [1]: https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#enums
[`const` assertions where added in TypeScript 3.4][1] and can be used to create enum-like objects in plain JavaScript, that act like TypeScript enums, but has none of the downsides of TypeScript enums. [1]: https://devblogs.microsoft.com/typescript/announcing-typescript-3-4/#const-assertions
[TypeScript enums][1] are an unusual TypeScript feature, because it's one of the only features that is "not a type-level extension of JavaScript". This means TypeScript generates custom code for enums, which can cause a bunch of issues, especially as this custom code can be built differently depending on which bundler you use, and because of this, many people discourage the use of enums: - [The Dangers of TypeScript Enums][2] - [Tidy TypeScript: Prefer union types over enums][3] - [TypeScript: Handbook - Enums # Objects vs Enums][4] I've added an ESLint rule that forbids TypeScript enums, as in most cases, it's better to use string literals instead, e.g. like `type a = "a" | "b" | "c";`. [1]: https://www.typescriptlang.org/docs/handbook/enums.html#string-enums [2]: https://dev.to/azure/the-dangers-of-typescript-enums-55pd [3]: https://fettblog.eu/tidy-typescript-avoid-enums/ [4]: https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## develop #4580 +/- ##
===========================================
+ Coverage 75.10% 79.85% +4.75%
===========================================
Files 135 143 +8
Lines 16498 16499 +1
Branches 510 519 +9
===========================================
+ Hits 12390 13176 +786
+ Misses 3997 3218 -779
+ Partials 111 105 -6
Flags with carried forward coverage won't be shown. Click here to find out more.
|
@aloisklink Thank you for being attentive to details. As a non TS programmer I cannot fully appreciate all the nuances, but I have experience with other languages that support this. Enums originated quite a time ago in static typed languages, and in majority of cases they are implemented as numeric constants under the hood. Like in c++: enum Weekday {
Monday, // 0
Tuesday // 1
} And such a notation it is absolutely valid (not checking syntax, though): Weekday(0); So the statement
related not only to typescript, but rather to the the nature of enums. There are many cases when these could be type-casted dynamically to Speaking about string enums, there was no such a thing in older c++ versions (I am not following latest standards), so there was some tricks to do the same for strings, including but not limited to:
None of the latter are memory-economic, so there was even some more evil hacks to achieve desired behavior. I've read the articles you provided and from my background the arguments "to avoid them unless you are sure" as well as "not being type safe" are not strong enough. They behave almost exactly the same way as in other languages, and I consider it as expected behavior. Since there is a Nevertheless, I am OK "string constants" as a preferred way in that case. Perhaps, enums can confuse other developers who never faced it. Or we may run into an issue with it later on. The main thing that can cause misunderstanding is that a user's configuration contains a JSON with From my perspective (I hope I don't hurt anyone's feelings) the whole typescript is somewhat an imperfect patch trying to fix JavaScript "weakly" typed design (not unlike PHP) and resulting scalability problem. So it does not really matter to me which type to use. What matters is that it is better to choose one option and to stick with it for the whole project, thus your change that forbids enums is absolutely valid. TLDR, summarize:
@sidharthv96 as a main reviewer of Sankey diagrams, what do you think? |
I agree. That's actually the main issue with TypeScript enums, it's a TypeScript-only feature that doesn't exist in JavaScript. Pretty much all modern TypeScript features are only type-level features. E.g., you can delete all the type information, and you'll be left with perfectly valid JavaScript code. TypeScript enums were added to the language a long time ago, and are different because they require custom JavaScript code to be generated (there's even been talk about potentially deprecating it, although it's a bit unlikely since it will break a lot of legacy code). There's even a proposal for enums to officially be added to JavaScript (see https://github.com/rbuckton/proposal-enum), and if that gets added, it might break existing TypeScript enum code, since they use the same syntax. (TypeScript enums are also excluded from the ECMAScript proposal: Type Annotations for this same reason). It's generally safe to use TypeScript enum is private files, but if you're making a public API, then using a TypeScript enum usually isn't a good idea. From a C++ perspective, imagine TypeScript enums to be a feature that isn't part of the official C++ standard, but something that's only supported in a specific C++ compiler.
👍 That's good to hear! My vote is to remove them and forbid them, since otherwise, once we have them, we wouldn't be able to remove them without breaking backwards compatibility, but I'd love to get the comments from anybody else that has TypeScript experience. |
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [mermaid](https://togithub.com/mermaid-js/mermaid) | [`10.2.4` -> `10.3.0`](https://renovatebot.com/diffs/npm/mermaid/10.2.4/10.3.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/mermaid/10.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/mermaid/10.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/mermaid/10.2.4/10.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/mermaid/10.2.4/10.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>mermaid-js/mermaid (mermaid)</summary> ### [`v10.3.0`](https://togithub.com/mermaid-js/mermaid/releases/tag/v10.3.0): 10.3.0 [Compare Source](https://togithub.com/mermaid-js/mermaid/compare/v10.2.4...v10.3.0) #### What's Changed ##### Features - Sankey diagrams by [@​nirname](https://togithub.com/nirname) in [https://github.com/mermaid-js/mermaid/pull/4502](https://togithub.com/mermaid-js/mermaid/pull/4502) - Feature/1838 actor creation destruction by [@​Valentine14th](https://togithub.com/Valentine14th) in [https://github.com/mermaid-js/mermaid/pull/4466](https://togithub.com/mermaid-js/mermaid/pull/4466) - Vertical branches in Git Diagram by [@​mastersibin](https://togithub.com/mastersibin) in [https://github.com/mermaid-js/mermaid/pull/4639](https://togithub.com/mermaid-js/mermaid/pull/4639) - Use JSON Schema to define and document `MermaidConfig` by [@​aloisklink](https://togithub.com/aloisklink) in [https://github.com/mermaid-js/mermaid/pull/4112](https://togithub.com/mermaid-js/mermaid/pull/4112) - Remove the test checking whether the JSON Schema default config matched the old default config by [@​aloisklink](https://togithub.com/aloisklink) in [https://github.com/mermaid-js/mermaid/pull/4610](https://togithub.com/mermaid-js/mermaid/pull/4610) - Fixes support of the macro `ContainerQueue_Ext` for C4 diagrams definition. by [@​kislerdm](https://togithub.com/kislerdm) in [https://github.com/mermaid-js/mermaid/pull/4577](https://togithub.com/mermaid-js/mermaid/pull/4577) ##### Bugfixes - Make quadrant chart options TypeScript types optional by [@​aloisklink](https://togithub.com/aloisklink) in [https://github.com/mermaid-js/mermaid/pull/4602](https://togithub.com/mermaid-js/mermaid/pull/4602) - Remove double parsing by [@​nirname](https://togithub.com/nirname) in [https://github.com/mermaid-js/mermaid/pull/4587](https://togithub.com/mermaid-js/mermaid/pull/4587) - Fix flowchart tooltip typing bug by [@​lishid](https://togithub.com/lishid) in [https://github.com/mermaid-js/mermaid/pull/4562](https://togithub.com/mermaid-js/mermaid/pull/4562) - Bug/4590 allow notes identical to keywords by [@​ibrahimWassouf](https://togithub.com/ibrahimWassouf) in [https://github.com/mermaid-js/mermaid/pull/4597](https://togithub.com/mermaid-js/mermaid/pull/4597) - feat: allow specifying on which weekday a tickInterval should start by [@​leinelissen](https://togithub.com/leinelissen) in [https://github.com/mermaid-js/mermaid/pull/4634](https://togithub.com/mermaid-js/mermaid/pull/4634) - Split formatted markdown strings with unicode support. by [@​sidharthv96](https://togithub.com/sidharthv96) in [https://github.com/mermaid-js/mermaid/pull/4470](https://togithub.com/mermaid-js/mermaid/pull/4470) - fix: Mind maps handles `-` signs in node ids/text by [@​knsv](https://togithub.com/knsv) ##### Chores - Remove all TypeScript enums and forbid them in ESLint by [@​aloisklink](https://togithub.com/aloisklink) in [https://github.com/mermaid-js/mermaid/pull/4580](https://togithub.com/mermaid-js/mermaid/pull/4580) - refactor accessibility by [@​Yokozuna59](https://togithub.com/Yokozuna59) in [https://github.com/mermaid-js/mermaid/pull/4551](https://togithub.com/mermaid-js/mermaid/pull/4551) - chore: Reduce codecov pushes by [@​sidharthv96](https://togithub.com/sidharthv96) in [https://github.com/mermaid-js/mermaid/pull/4604](https://togithub.com/mermaid-js/mermaid/pull/4604) - Run PR-labeler-config-validator only if config changes by [@​sidharthv96](https://togithub.com/sidharthv96) in [https://github.com/mermaid-js/mermaid/pull/4607](https://togithub.com/mermaid-js/mermaid/pull/4607) - chore(deps): update all minor dependencies (minor) by [@​renovate](https://togithub.com/renovate) in [https://github.com/mermaid-js/mermaid/pull/4624](https://togithub.com/mermaid-js/mermaid/pull/4624) - Update all patch dependencies (patch) by [@​renovate](https://togithub.com/renovate) in [https://github.com/mermaid-js/mermaid/pull/4566](https://togithub.com/mermaid-js/mermaid/pull/4566) - Update all patch dependencies (patch) by [@​renovate](https://togithub.com/renovate) in [https://github.com/mermaid-js/mermaid/pull/4581](https://togithub.com/mermaid-js/mermaid/pull/4581) - Rename workflow jobs by [@​sidharthv96](https://togithub.com/sidharthv96) in [https://github.com/mermaid-js/mermaid/pull/4574](https://togithub.com/mermaid-js/mermaid/pull/4574) - Removed unused code in state diagrams by [@​nirname](https://togithub.com/nirname) in [https://github.com/mermaid-js/mermaid/pull/4631](https://togithub.com/mermaid-js/mermaid/pull/4631) - chore(deps): update all patch dependencies (patch) by [@​renovate](https://togithub.com/renovate) in [https://github.com/mermaid-js/mermaid/pull/4623](https://togithub.com/mermaid-js/mermaid/pull/4623) - chore: remove unused `devDependency` on coveralls by [@​aloisklink](https://togithub.com/aloisklink) in [https://github.com/mermaid-js/mermaid/pull/4641](https://togithub.com/mermaid-js/mermaid/pull/4641) - Allow entity diagram attribute names to start with asterisk by [@​ibrahimWassouf](https://togithub.com/ibrahimWassouf) in [https://github.com/mermaid-js/mermaid/pull/4588](https://togithub.com/mermaid-js/mermaid/pull/4588) - Bug/4592 fix new line padding class diagram by [@​ibrahimWassouf](https://togithub.com/ibrahimWassouf) in [https://github.com/mermaid-js/mermaid/pull/4633](https://togithub.com/mermaid-js/mermaid/pull/4633) - Fix graph not loading when the img loads too fast or fail to load by [@​pierrickouw](https://togithub.com/pierrickouw) in [https://github.com/mermaid-js/mermaid/pull/4496](https://togithub.com/mermaid-js/mermaid/pull/4496) - convert `cypress/helpers/util.js` to ts by [@​Yokozuna59](https://togithub.com/Yokozuna59) in [https://github.com/mermaid-js/mermaid/pull/4552](https://togithub.com/mermaid-js/mermaid/pull/4552) - build(deps-dev): bump word-wrap from 1.2.3 to 1.2.4 by [@​dependabot](https://togithub.com/dependabot) in [https://github.com/mermaid-js/mermaid/pull/4652](https://togithub.com/mermaid-js/mermaid/pull/4652) - chore(deps): update all minor dependencies (minor) by [@​renovate](https://togithub.com/renovate) in [https://github.com/mermaid-js/mermaid/pull/4663](https://togithub.com/mermaid-js/mermaid/pull/4663) - chore(deps): update all patch dependencies (patch) by [@​renovate](https://togithub.com/renovate) in [https://github.com/mermaid-js/mermaid/pull/4662](https://togithub.com/mermaid-js/mermaid/pull/4662) ##### Documentation - Sankey: Remove duplicated examples by [@​nirname](https://togithub.com/nirname) in [https://github.com/mermaid-js/mermaid/pull/4595](https://togithub.com/mermaid-js/mermaid/pull/4595) - Release docs by [@​sidharthv96](https://togithub.com/sidharthv96) in [https://github.com/mermaid-js/mermaid/pull/4493](https://togithub.com/mermaid-js/mermaid/pull/4493) - Update latest news section by [@​huynhicode](https://togithub.com/huynhicode) in [https://github.com/mermaid-js/mermaid/pull/4495](https://togithub.com/mermaid-js/mermaid/pull/4495) - Fix Typo by [@​ryru](https://togithub.com/ryru) in [https://github.com/mermaid-js/mermaid/pull/4567](https://togithub.com/mermaid-js/mermaid/pull/4567) - Docs: add ChatGPT plugin blog post by [@​huynhicode](https://togithub.com/huynhicode) in [https://github.com/mermaid-js/mermaid/pull/4570](https://togithub.com/mermaid-js/mermaid/pull/4570) - Fix relative link to theme variables list by [@​ibrahimWassouf](https://togithub.com/ibrahimWassouf) in [https://github.com/mermaid-js/mermaid/pull/4573](https://togithub.com/mermaid-js/mermaid/pull/4573) - Fix docs:dev by [@​sidharthv96](https://togithub.com/sidharthv96) in [https://github.com/mermaid-js/mermaid/pull/4598](https://togithub.com/mermaid-js/mermaid/pull/4598) - Docs: update link - "Join the Community" by [@​huynhicode](https://togithub.com/huynhicode) in [https://github.com/mermaid-js/mermaid/pull/4601](https://togithub.com/mermaid-js/mermaid/pull/4601) - Support docs:dev in docker by [@​nirname](https://togithub.com/nirname) in [https://github.com/mermaid-js/mermaid/pull/4599](https://togithub.com/mermaid-js/mermaid/pull/4599) - docs(flowchart): add documentation on multiple nodes style by [@​tomperr](https://togithub.com/tomperr) in [https://github.com/mermaid-js/mermaid/pull/4600](https://togithub.com/mermaid-js/mermaid/pull/4600) - Avoid downloading avtars everytime on docs:dev by [@​sidharthv96](https://togithub.com/sidharthv96) in [https://github.com/mermaid-js/mermaid/pull/4603](https://togithub.com/mermaid-js/mermaid/pull/4603) - docs: Fix checkbox syntax by [@​guilhermgonzaga](https://togithub.com/guilhermgonzaga) in [https://github.com/mermaid-js/mermaid/pull/4646](https://togithub.com/mermaid-js/mermaid/pull/4646) - Fix the "Edit this page on GitHub" link in Vitepress documentation for the Mermaid Config pages by [@​aloisklink](https://togithub.com/aloisklink) in [https://github.com/mermaid-js/mermaid/pull/4640](https://togithub.com/mermaid-js/mermaid/pull/4640) - Support MERMAID_RELEASE_VERSION in docs. by [@​sidharthv96](https://togithub.com/sidharthv96) in [https://github.com/mermaid-js/mermaid/pull/4612](https://togithub.com/mermaid-js/mermaid/pull/4612) - Docs: update Latest News section by [@​huynhicode](https://togithub.com/huynhicode) in [https://github.com/mermaid-js/mermaid/pull/4655](https://togithub.com/mermaid-js/mermaid/pull/4655) - added Typora to integrations list by [@​kgilbert78](https://togithub.com/kgilbert78) in [https://github.com/mermaid-js/mermaid/pull/4666](https://togithub.com/mermaid-js/mermaid/pull/4666) - Docs: Corrects name of C4 link by [@​Incognito](https://togithub.com/Incognito) in [https://github.com/mermaid-js/mermaid/pull/4660](https://togithub.com/mermaid-js/mermaid/pull/4660) - Fix a typo by [@​gjtorikian](https://togithub.com/gjtorikian) in [https://github.com/mermaid-js/mermaid/pull/4396](https://togithub.com/mermaid-js/mermaid/pull/4396) #### New Contributors - [@​ryru](https://togithub.com/ryru) made their first contribution in [https://github.com/mermaid-js/mermaid/pull/4567](https://togithub.com/mermaid-js/mermaid/pull/4567) - [@​ibrahimWassouf](https://togithub.com/ibrahimWassouf) made their first contribution in [https://github.com/mermaid-js/mermaid/pull/4573](https://togithub.com/mermaid-js/mermaid/pull/4573) - [@​kislerdm](https://togithub.com/kislerdm) made their first contribution in [https://github.com/mermaid-js/mermaid/pull/4577](https://togithub.com/mermaid-js/mermaid/pull/4577) - [@​leinelissen](https://togithub.com/leinelissen) made their first contribution in [https://github.com/mermaid-js/mermaid/pull/4634](https://togithub.com/mermaid-js/mermaid/pull/4634) - [@​pierrickouw](https://togithub.com/pierrickouw) made their first contribution in [https://github.com/mermaid-js/mermaid/pull/4496](https://togithub.com/mermaid-js/mermaid/pull/4496) - [@​mastersibin](https://togithub.com/mastersibin) made their first contribution in [https://github.com/mermaid-js/mermaid/pull/4639](https://togithub.com/mermaid-js/mermaid/pull/4639) - [@​kgilbert78](https://togithub.com/kgilbert78) made their first contribution in [https://github.com/mermaid-js/mermaid/pull/4666](https://togithub.com/mermaid-js/mermaid/pull/4666) - [@​Incognito](https://togithub.com/Incognito) made their first contribution in [https://github.com/mermaid-js/mermaid/pull/4660](https://togithub.com/mermaid-js/mermaid/pull/4660) - [@​gjtorikian](https://togithub.com/gjtorikian) made their first contribution in [https://github.com/mermaid-js/mermaid/pull/4396](https://togithub.com/mermaid-js/mermaid/pull/4396) **Full Changelog**: mermaid-js/mermaid@v10.2.4...v10.3.0 </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/levaintech/contented). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4xMS4wIiwidXBkYXRlZEluVmVyIjoiMzYuMTEuMCIsInRhcmdldEJyYW5jaCI6Im1haW4ifQ==--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
📑 Summary
TypeScript enums are an unusual TypeScript feature, because it's one of the only features that is "not a type-level extension of JavaScript".
This means TypeScript generates custom code for enums, which can cause a bunch of issues, especially as this custom code can be built differently depending on which bundler you use, and because of this, many people discourage the use of enums:
In fact, even the official TypeScript handbook says:
I've also added an ESLint rule to ban TypeScript enums, using the
no-restricted-syntax
ESLint rule.Better alternatives for TypeScript enums
For public APIs (e.g. that non-Mermaid users will use), it's better to use string literals, e.g.:
For internal use,
const
assertions where added in TypeScript 3.4 and can be used to create enum-like objects in plain JavaScript, that act like TypeScript enums, but has none of the downsides of TypeScript enums.Using a JavaScript object and
as const
performs pretty much exactly the same as a TypeScript enum, without the downsides of a TypeScript enum:📏 Design Decisions
Important: This is a breaking change to the MermaidConfig Sankey diagram type. However, since the Sankey diagram PR was only merged yesterday (see #4502), as long as this PR is merged before the next Mermaid release, this change will be fine.
📋 Tasks
Make sure you
develop
branch