At the express suggestion of a package maintainer whose package has over 36 million weekly downloads, I submit the following (original submission/comment is https://github.com/chalk/chalk/pull/373#issuecomment-592269429):
I wrote:
@babel/preset-typescript gets about 3.7 million weekly downloads; typescript gets about 7.9 million.
This is not a rigorous analysis... but, because the problem arises with
const enumbeing unsupported by@babel/preset-typescript(because it only works with code that conforms toisolatedModules), that means about half of the typescript projects out there can't use chalk 3.x.
@babel/preset-typescriptalso doesn't fully support TS namespaces. The TS maintainers have publicly said that ES6 modules are the future; on the other hand, they've also publicly said they have zero plans to remove namespaces from the language. I don't know for certain, but I expect they would not be open to removingconst enumeither.There is a plugin (babel-plugin-const-enum) that can help with the
const enumsituation. However, it's not a wonderful solution because those of us who usetscto typecheck — which is everyone sincebabel/preset-typescriptdoesn't do any typechecking — need to disable theisolatedModulesoption. But it's important to have that option in place in projects using@babel/preset-typescript, especially in larger projects, to ensure that contributors don't commit code that won't work with it.In summary: many TypeScript projects won't be able to use chalk 3.x if it retains
const enum. It's not really any one's fault, it's just how things are given the technical constraints of@babel/preset-typescriptand the practical need to typecheck withtscin a manner that detects code that isn't compatible.I'm sure none of the above will convince you to change your mind, and there's certainly no resentment on my part. I wasn't sure how many people who encounter this issue understand the core of the problem, so I hope my comment is helpful. Thanks for all your hard work on this wonderful library!
The maintainer replied:
They don't need to remove it, just officially discourage it ...
const enumis a real pain-point for users. You can fix Chalk here, but there will be lots of other projects usingconst enumand are you going to spend time on this every time you encounter a project usingconst enum?
Is there something I'm missing as a consumer of this library running into problems with isolatedModules clashing with const enum?
Is there something the package maintainer could do to alleviate the problem in a manner that doesn't sacrifice the performance gains of const enum?
Is there something the TypeScript maintainers can do to help improve the situation?
cf. https://github.com/microsoft/TypeScript/issues/30590 and https://github.com/facebook/create-react-app/pull/4837#issuecomment-430107471.
Much thanks for your time and consideration!
I think the linked PR is ~bad~ very good. const enum implies there's no corresponding runtime object, but we do have a runtime object corresponding to this declaration.
Moreover, the package docs imply that it's expected to write { level: 2 } in code - it seems like a symbolic name for these values is not strictly necessary.
So it seems like the ~status quo~ proposed PR is the best of all worlds -- users (both TS and JS!) can refer to the levels through symbolic names if they want, or use the documented 0-3 values if they really need to save a dozenish bytes of package size.
The intended use case of const enum would be for a value that probably doesn't even escape the file it's declared in, or at the very least doesn't escape the project it's declared in. Leaking a const enum outside your project scope is very dangerous for versioning because you can easily get into a state where two people who wrote code referring to the same symbolic name end up with different values.
Really all we can do is ask that people understand the implications of const enum - just like you wouldn't ask JS consumers to run a custom Babel transformer to use your library, you shouldn't expect TS consumers to consume const enums unless there's some very good reason. Provide symbolic, non-inlined names through regular enums if that's desired, or use nonsymbolic values like 2 if those make sense.
Note: I originally misread which direction the linked PR changes things, so please reread the above comment if you read it earlier.
const enum implies there's no corresponding runtime object, but we do have a runtime object corresponding to this declaration.
This was not intended: https://github.com/chalk/chalk/pull/373#issuecomment-596226057
The intended use case of const enum would be for a value that probably doesn't even escape the file it's declared in, or at the very least doesn't escape the project it's declared in.
This is not clear in the docs either.
Really all we can do is ask that people understand the implications of const enum
It's hard to understand implications that is not clear by its docs.
you shouldn't expect TS consumers to consume const enums unless there's some very good reason.
What are you saying here? That const enum should not be used in ambient files at all?
const enums are often misused. - https://github.com/facebook/create-react-app/pull/4837#issuecomment-430107471
Maybe this is a hint that the docs are not good enough? It's not like us users want to use something incorrectly.
Most helpful comment
I think the linked PR is ~bad~ very good.
const enumimplies there's no corresponding runtime object, but we do have a runtime object corresponding to this declaration.Moreover, the package docs imply that it's expected to write
{ level: 2 }in code - it seems like a symbolic name for these values is not strictly necessary.So it seems like the ~status quo~ proposed PR is the best of all worlds -- users (both TS and JS!) can refer to the levels through symbolic names if they want, or use the documented
0-3values if they really need to save a dozenish bytes of package size.The intended use case of
const enumwould be for a value that probably doesn't even escape the file it's declared in, or at the very least doesn't escape the project it's declared in. Leaking aconst enumoutside your project scope is very dangerous for versioning because you can easily get into a state where two people who wrote code referring to the same symbolic name end up with different values.Really all we can do is ask that people understand the implications of
const enum- just like you wouldn't ask JS consumers to run a custom Babel transformer to use your library, you shouldn't expect TS consumers to consumeconst enums unless there's some very good reason. Provide symbolic, non-inlined names through regularenums if that's desired, or use nonsymbolic values like2if those make sense.