-
-
Notifications
You must be signed in to change notification settings - Fork 919
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
feat(helpers): new method enumValue #1920
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method closely resembles how helpers.arrayElement and objectValue work, so we should move it to the helpers module instead.
And dont forget to run pnpm run preflight
when you are ready.
How will this method work in JavaScript given that enums are typescript-specific? |
Funny answer: That's the funny part, it wont Technical correct answer: enum Color { Red, Green, Blue }
var Color;
(function (Color) {
Color[Color["Red"] = 0] = "Red";
Color[Color["Green"] = 1] = "Green";
Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {})); So normally you are BY FAR more better suited with setups like Then there are TL;DR: enums in TS are a total misconcept and failure and Microsoft / the TS Team knows that and communicate that in the past already (I just sadly don't find a source directly for that). So there is only few really case for using enums (and the should be used carefully):
When using them in a library (like FakerJS), always ensure they are 100% optional and you can always call the function in a readable easy way like using string literals. |
I call BS. An enum as you pointed out is simply converted to a JS object. That means you can use it like a JS object. That means you can use all methods as you would in TS. The catch is that those enum objects need to be handled a little bit differently on our side. String enums work the same as normal objects would. // in js
const myObject = Object.freeze({
FOO: 'bar',
HELLO: 'world',
});
faker.helpers.objectKey(myObject); // 'FOO' | 'HELLO'
faker.helpers.enumKey(myObject); // 'FOO' | 'HELLO'
faker.helpers.objectValue(myObject); // 'bar' | 'world'
faker.helpers.enumValue(myObject); // 'bar' | 'world'
// in ts
enum MyEnum {
FOO: 'bar',
HELLO: 'world',
}
faker.helpers.objectKey(MyEnum ); // 'FOO' | 'HELLO'
faker.helpers.enumKey(MyEnum); // 'FOO' | 'HELLO'
faker.helpers.objectValue(MyEnum ); // 'bar' | 'world'
faker.helpers.enumValue(MyEnum); // 'bar' | 'world' Numeric enums are working (as you pointed out) a bit differently. You have to know this when working with enums (which sucks, no doubt). So while not working as expected, you can make them work! // in js
const myObject = Object.freeze({
FOO: 0,
BAR: 1,
// here is the catch
0: 'FOO',
1: 'BAR',
});
faker.helpers.objectKey(myObject); // 'FOO' | 'HELLO' | 0 | 1
faker.helpers.enumKey(myObject); // 'FOO' | 'HELLO'
faker.helpers.objectKey(myObject); // 'FOO' | 'HELLO' | 0 | 1
faker.helpers.enumValue(myObject); // 0 | 1
// in ts
enum MyEnum {
FOO: 0,
BAR: 1,
}
faker.helpers.objectKey(MyEnum); // 'FOO' | 'HELLO' | 0 | 1
faker.helpers.enumKey(MyEnum); // 'FOO' | 'HELLO'
faker.helpers.objectKey(MyEnum); // 'FOO' | 'HELLO' | 0 | 1
faker.helpers.enumValue(MyEnum); // 0 | 1 By providing the helper functions we essentially provide a bridge that allows users to handle enums as they expect.
Source? |
@xDivisionByZerox please be careful in not getting personally and callout terms like "BS" Yes indeed I'm talking about nano-seconds performance improvements. But also even on a code readability perspective it's possible to confuse folks with ordinal enums more then it helps. |
You gave out straight-up wrong information. Why am not allowed to call that out? I wasn't calling YOU out but the information you gave. Edit: Edit2: |
Could one extend objectKey/objectValue instead to specifically handle the case of it being passed a TS enum? |
This would degrade the usability of those methods for user defined objects, that actually use numeric keys. So no. |
This would be the only Faker method which requires typescript to call into right? I think that would be worthy of calling out in the documentation for this function if accepted. |
AFAICT this will also work with plain json object pseudo enums (it is basically the same as objectValue while ignoring numeric keys). faker.helpers.enumValue(Color); Works for both: enum Color { Red, Green, Blue } and const Color = { Red: 0, Green: 1, Blue: 2 } And still provides a minuscule readability improvement over We might want to add a hint that it ignores numeric keys though (and add an |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last change, then this is good to go IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I sadly identified some TypeScript problems: TS-playground
So while the runtime code is okay, the actual return type of the function is not real-world usable and therefore lacks the usability for what the function is originally planned for.
Right now I didn't get the types managed myself, hopefully someone of you have more luck.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those type errors can be fixed with the following changes.
It slightly reduces the DX for the return types of String enums.
@Shinigami92 Any suggestions on how to modify the tests to catch the type errors (for future refactorings)?
Co-authored-by: ST-DDT <ST-DDT@gmx.de>
Co-authored-by: ST-DDT <ST-DDT@gmx.de>
…nge comment of generic types of enumValue
Co-authored-by: ST-DDT <ST-DDT@gmx.de>
@matthewmayer please also approve or write a new review comment |
With this method it is possible to get a random value from an enum.
This is very useful for not having to harcode an enum when generating fake data.
Docs-Preview