-
Notifications
You must be signed in to change notification settings - Fork 118
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
Normalize construction of user facing enums #1534
Normalize construction of user facing enums #1534
Conversation
744d42e
to
855baab
Compare
enum
s855baab
to
337ed11
Compare
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.
Cool! This should be a big QoL improvement
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.
Wow! There's quite a lot going on... but this should be a really nice improvement.
I'll just ask one question for now. If we take something like
decodeStartChildWorkflowExecutionFailedCause(activation.failed.cause)
It would be nice if this looked more like
decode(activation.failed.cause)
Do you see any possibilities in that direction?
( | ||
input: ShortStringEnumKey | `${Prefix}${ShortStringEnumKey}` | ProtoEnumValue | null | undefined | ||
) => ProtoEnumValue | undefined, // | ||
(input: ProtoEnumValue | null | undefined) => ShortStringEnumKey | undefined, // |
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.
When does null
occur?
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.
The protobuf-to-ts transpiler makes every field MyProtoType | null | undefined
. That's just the way it is, unfortunately, so decode(...)
must accept that.
Now, I don't think there's any legitimate use case for encode(...)
to receive null
as input, but just for symetry, most of our encode
functions have followed that pattern anyway.
You would need to pass something that represents the enum-const-object itself, e.g. I think that might be possible, by adding a symbol property on the enum-const-object to record the mapping and reverse-mapping tables. I wouldn't dig into that possibility at this point though. |
What was changed
This PR normalizes conventions around user facing
enums
in the TS SDK.More specifically, it features the following conventions:
No more redundant prefixes on enum values.
For example:
No more 'UNSPECIFIED' values in user facing enums; TypeScript's
undefined
already means that."Enum values" are now of type string, and the "enum" themselves are now implemented using
const
objects, with a string union type defined from all values of the const object. That makes it possible for users to simply pass the string representation of an enum value, without having to import and refer to the enum definition object. That's much more TS idiomatic and is better supported by TS code editors.The preceding example can therefore be further reduced down to:
The const object is preserved (i.e not completely replaced by the union of strings type), for backward compatibility reasons, but also because it plays better in regard to documentation of each enum values.
We preserve build-time backward compatibility for enum values that existed before.
For example, the following code will still compile, but will report a deprecation on
ParentClosePolicy.PARENT_CLOSE_POLICY_ABANDON
.We maintain the SCREAMING_SNAKE_CASE format for enum values
For "user facing enums" to/from "proto enums" conversions, we normalize on a
encodeEnumName(string): ProtoEnumValue
and adecodeEnumName(ProtoEnumValue): string
functions, whereProtoEnumValue
really is the numerical value of the proto enum value. This ensures uniformity for all enum types, without risk of getting the proto definitions imported in the Workflow sandbox (which would significantly increase the per-workflow memory footprint).