Uh oh!
There was an error while loading. Please reload this page.
Ensure enum members syntactically determinable to be strings do not get reverse mappings - #57686
Conversation
…et reverse mappings. Co-authored-by: frigus02 <3579251+frigus02@users.noreply.github.com>
Jan Kühle (frigus02)
left a comment
There was a problem hiding this comment.
Thank you, Andrew. I'm personally in favor of this approach.
Uh oh!
There was an error while loading. Please reload this page.
Jake Bailey (jakebailey)
commented
Mar 8, 2024
I personally agree with this, and so think I prefer this PR.
Is there some way we can instead use |
Andrew Branch (andrewbranch)
commented
Mar 8, 2024
This PR moves in that direction, but we can't fully control emit by import{SomeOtherStringEnum}from'./m';enumFoo{A=SomeOtherStringEnum.StringValue}This works in non-isolatedModules |
Andrew Branch (andrewbranch)
commented
Mar 12, 2024
TypeScript Bot (@typescript-bot) pack this |
Hey Andrew Branch (@andrewbranch), I've packed this into an installable tgz. You can install it for testing by referencing it in your and then running There is also a playground for this build and an npm module you can use via |
Jake Bailey (jakebailey)
commented
Mar 12, 2024
FWIW esbuild does it the same way this PR does so I am all for it: https://jakebailey.dev/esbuild-playground/#v3=PTAEAEDMEsBsFMB2BDAtvAXKAxge0TAOYB0AVgM74BQA3laKAERIAuATgJ4AKu0iL5RlgDajYHwAm8AB7EB0xgF0ANPSaRcbVMhZCm8cqkZUAvlSogIMBCnRZJMueWlVoqAA6aWoGqABCAIIASqAmoJBsuKigAOQARshsMQDcVEgArtEAYri4PqABoAC8oAAGACQ0gUEmpaFUQA |
Andrew Branch (andrewbranch)
commented
Mar 12, 2024
Jake and Ryan have expressed support for this. Can I have a ✅? 😄 |
Uh oh!
There was an error while loading. Please reload this page.
Unblocks #56736?
In #56164, we decided that under
isolatedModules, (from the notes) “enum members referencing another external enum must always be numeric, or explicitly converted to a string. Otherwise, it is an error.” This proposed rule has since undergone a number of interpretations on its way to an attempt to implement it. In #56153 (comment), Ryan stated that we should issue an error when “an enum initializer expression that isn't a string literal has a string type.” In #56736, Jan Kühle (@frigus02) worked off this statement, but interpreted “string literal” as any expression that could be evaluated to a known constant string value with single-file syntactic information only.An invariant guiding the decision is that error-free (under
--isolatedModules) code should produce semantically equivalent JS betweents.transpileModuleandtsc. Currently, that’s violated by this test case:This is currently error-free, but the emit varies.
tsc:ts.transpileModule:The problematic part isn’t the inlining of the value
"bar"; it’s the fact that the transpiled output includes a reverse mapping when it absolutely shouldn’t.To fix this, we either need an error under
isolatedModulesor we need to fix thets.transpileModuleemit. Both Ryan’s formulation of the rule proposed in #56164 and Jan Kühle (@frigus02)’s expanded interpretation in #56736 make this code an error. This PR fixes the emit by determining that the initializer is definitely going to be a string without looking at any type or extra-file info.I’m fine with adopting Ryan’s very strict rule instead of this, but it does seem like fairly low hanging fruit here. I’m less of a fan of the approach currently in #56736, since constant evaluation feels like the wrong thing to control whether a reverse mapping gets created, even though that’s what actually controls the emit today.