'Typescript const enum alternative
More and more modern Typescript transpilers have moved toward a strategy of per-module transpilation, which significantly increases build speed, but eliminates the possibility for cross-module const enum
usage, since transpilation of them requires type information.
I have a significant amount of const enums
that when used without the inlining that const
provides:
- End up being hundreds of KBs even after minification due to long property names
- Leak internal, backend property names that I don't want public
Right now I have these const enum
definitions auto generated from backend native code. As a contrived example, you can imagine I work at Apple and have a great big const enum of every hardware device.
const enum HardwareType {
Apple1 = 0,
// ...
iPhoneX = 412,
// ...
iPhoneUltraXD = 499, // Some theoretical unannounced iPhone
}
If I just change const enum HardwareType
to enum HardwareType
, in addition to bumping up my bundle size, I've now leaked the new "iPhone Ultra XD" to the public.
I see that something like Terser supports the --mangle-props
option, but even that seems to be warned against in the official docs and also would mean creating a regex that covers every single HardwareType
? Not to mention that's just my contrived example and I have dozens of these enums in reality with hundreds of values.
I'd really like to use the latest tech for application bundling, but is there really not a better option out there for compile time inlining of constant values?
Solution 1:[1]
const enum
is not very secure in hiding original names. As you can see in that playground typescript compiler adds original names in comments:
// Input:
const enum Fruites {
Apple = 1,
Banana = 2
}
const x = Fruites.Apple
const y = Fruites.Banana
// Output:
"use strict";
const x = 1 /* Apple */;
const y = 2 /* Banana */;
If your a really wondering to use the latest tech for application bundling and want to hide some secret names from output files, try to use esbuild-loader or esbuild itself. It support define option that allows you to replace some secret naming with meaningless values in compilation time like that
define: {
"secrets.hardwareType.iPhoneUltraXD": "499"
}
and safely use the defined value in source code
// Source code:
if (deviceId === secrets.hardwareType.iPhoneUltraXD) {
// Bundled code:
if(deviceId===499){
define
option could be initiated in webpack or esbuild config file with any computed values (even with required json files) so you have no limit in count of compile-time definitions.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Mikhail Sereniti |