Created
January 3, 2023 19:36
-
-
Save squarism/de5ac4e3296c30388fdb59a50820ab64 to your computer and use it in GitHub Desktop.
Typescript Enums are Cursed
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Theo's Enum Avoidance, Implemented | |
// https://www.youtube.com/watch?v=Anu8vHXsavo | |
// don't do this --------------------------------------------------- | |
enum UserRole { | |
User, | |
Admin, | |
Staff | |
} | |
// because of this problem | |
if (UserRole.User) { | |
// this never fires | |
console.log("User is user.") | |
} | |
if (UserRole.Admin) { | |
console.log("Admin is admin.") | |
} | |
// you could get around this by checking against "the numbers" in the enum | |
let assignedRole = UserRole.Admin | |
if (assignedRole === UserRole.Admin) { | |
console.log("You were assigned a role of admin.") | |
} | |
assignedRole = UserRole.User | |
if (assignedRole === UserRole.User) { | |
console.log("You were assigned a role of user.") | |
} | |
// but essentially, he's saying this is unenforceable | |
// you DO get nice error messages at compile time. Try changing L30 to Staff | |
// > This comparison appears to be unintentional because the types | |
// > 'UserRole.User' and 'UserRole.Staff' have no overlap.(2367) | |
// other issues: | |
// 1. The value is implicitly the order. Switch Staff and Admin on L8 and L9. | |
// 2. Exporting an enum will not work as you think because JS does not have it. | |
// If you are writing a library, you need to enable `isolatedModules`. | |
// alternative --------------------------------------------------- | |
// avoiding using arbitary strings is entirely why I use enums | |
const UserRoles = ["User", "Admin", "Staff"] as const | |
// note: this is named this because of naming conflict above | |
type Role = typeof UserRoles[number] | |
type User = { | |
role: Role | |
} | |
// when you need the values and not the types, use the array of strings. | |
const Dropdown = () => { | |
const data = UserRoles.map(role => ({ value: role, label: role })) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment