Description
Describe the bug
In typescript, we can represent string enums like so:
export enum EnvironmentName {
DEV = 'dev',
QA = 'qa',
FOO = 'bar'
}
However, in all languages besides js, jsii compiles these so that the key name is used. For instance, python output looks like:
@jsii.enum(jsii_type="@example/my-package.EnvironmentName")
class EnvironmentName(enum.Enum):
DEV = "DEV"
QA = "QA"
FOO = "FOO"
When using the enum as a type, this doesn't matter, as the literal value is unimportant. But when outputting a string, Python developers are now outputting FOO
whereas TS/JS users of the same construct output bar
. This breaks interoperability.
Expected Behavior
The string representation of an enum value in all languages should match the source code. As noted in the jsii design tenants:
- jsii applications behave identically regardless of the language they are written in. It favors correctness over performance.
- Unsupported idioms will cause a compile-time error to be emitted.
- When prohibiting an idiom, jsii strives to provide an error message that gives the user insight into why the pattern cannot be supported.
Applications should behave identically, and if that is not possible, there should be a compiler error for string enums where the key and value do not match.
Current Behavior
An application which uses runtime validation of enum values will fail in languages other than JS. For instance:
export const validateEnv = (env: EnvironmentName) => {
if (Object.values(EnvironmentName).includes(env)) {
throw new TypeError(`Value "${env}" is not a valid environment name.`);
}
}
I believe this is because the JS assembly is used when calling Object.values()
, and the value passed in doesn't match JS values due to the serialization differences.
Reproduction Steps
- Create a construct library which uses a string enum's values inside functional code.
- Publish package to NPM and another supported target.
- Import the package in the target language and call the function.
- Observe output.
Possible Solution
Rework how JSII models string enum values. Not sure how complicated this is, but it seems important for correctness.
Additional Information/Context
No response
SDK version used
jsii=5.2.8; jsii-pacmak=1.89.0
Environment details (OS name and version, etc.)
MacOS 11.7.10