-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Declare non-const enums if preserveConstEnums is true #46626
Conversation
The TypeScript team hasn't accepted the linked issue #37774. If you can get it accepted, this PR will have a better chance of being reviewed. |
src/compiler/emitter.ts
Outdated
factory.createNodeArray( | ||
filter( | ||
node.modifiers, | ||
modifier => !printerOptions.isolatedModules || modifier.kind !== SyntaxKind.ConstKeyword |
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.
Alternatively this could be done when parsing vs. emitting const enums?
This doesn't fix #37774 if |
@jablko is this a proof of concept? When I skimmed the issue I didn't see that it had arrived at a single solution yet. |
It's a proposed solution: #37774 (comment), but you're right: It's awaiting feedback (issue and proposal). I think it's right because:
∴
The difference between this PR and a |
Based on the discussion at the December 1st design meeting, we aren't convinced that improving const enums is worthwhile, since people should be using the feature less over time rather than more. |
All of the const enum pitfalls remain if you don't use
|
I've added a commit to inline plain enums from referenced projects. Currently you get different behavior consuming .ts files and consuming the .d.ts outputs of those same files: const enums in .ts files are (ordinarily) compatible with This came up again here. An example is you can't use const enums from referenced projects with This PR fixes that, but now you get different behavior between .ts files and their .d.ts outputs when built with
Not inlining enums from referenced projects could be a problem, however. The latest commit solves that by inlining plain enums. Inlining all enums would open up compile-time vs. runtime version compatibility with published .d.ts outputs, but inlining plain enums from referenced projects is safe because they're part of the same build. The logic is that we inline const enums from .ts files, we use deconstified .d.ts outputs for referenced projects, so inline plain enums from referenced projects. |
To help with PR housekeeping, I'm going to close this PR while it's still waiting on its bug to be accepted. |
Currently if you
tsc --declaration --isolatedModules
, the compiler turns non-ambient const enums (.ts
files) into ambient const enums (.d.ts
files) that can't themselves be consumed with--isolatedModules
: Ambient const enums (values -- types are fine) are incompatible withisolatedModules
.In every other way
tsc --isolatedModules
ignores the const modifier -- treats const enums as non-const:.js
values (likepreserveConstEnums
)preserveConstEnums
)This PR doesn't emit the const modifier if
isolatedModules
is true, effectively suppressing the const modifier entirely in that case.tsc --declaration --isolatedModules
then turns non-ambient const enums into ambient non-const enums which can in turn be consumed with--isolatedModules
: #37774 (comment)The affected scenario is when you:
.d.ts
withisolatedModules: true
(currently: const modifiers preserved, this PR: const modifiers dropped).d.ts
:isolatedModules: true
: Currently: error. This PR: no error, values and imports preserved, same as all enums, (non-ambient) const enums included.isolatedModules: false
: Currently: values inlined, imports elided. This PR: same as withisolatedModules: true
(values and imports preserved).When a.d.ts
is produced withisolatedModules: true
and consumed withisolatedModules: false
, what's the point of inlining values and eliding imports? If you consume any part of the produced library that itself uses the const enum values, you'll end up importing the enum's.js
values.So this PR will only introduce imports that don't currently exist if you publish a library that declares const enum values it doesn't itself use, and in that case if you really want to publish isolatedModules-incompatible ambient const enums, produce its.d.ts
withisolatedModules: false
.Edit: Inlining enums from other projects comes with pitfalls:
Roughly this PR propagates today's isolatedModules const enum behavior transitively to
.d.ts
consumers.Fixes #37774