swc icon indicating copy to clipboard operation
swc copied to clipboard

const enum compile time evaluate

Open Brooooooklyn opened this issue 5 years ago • 23 comments

https://www.typescriptlang.org/docs/handbook/enums.html#const-enums

Brooooooklyn avatar Aug 06 '20 10:08 Brooooooklyn

It's not possible at the moment, as swc process file by file. babel also has same restriction.

kdy1 avatar Aug 06 '20 10:08 kdy1

I'm trying replace ts-jest in vue-next with @swc-node/jest, and I found that const enum would cause runtime error in test specs.

Brooooooklyn avatar Aug 06 '20 10:08 Brooooooklyn

I think using spack's system can be a solution.

Something like

bundle({
    constEnum: true,
    merge: false
})

?

Do you think it's acceptable?

(I'll provide better api)

kdy1 avatar Aug 13 '20 06:08 kdy1

I don't think spack satisfy with the vue-next use case.

And there are some other way to make swc working fine with jest in vue-next, I will do more research in future.

Note: TypeScript meet the same problem with the preserveConstEnums flag, so I think maybe I could try to fix it in jest-runtime.

Brooooooklyn avatar Aug 13 '20 06:08 Brooooooklyn

I can modify spack act like tsc

a.ts -> a.js b.ts -> b.ts

while handling const enums

Doesn't it fit the use case?

kdy1 avatar Aug 13 '20 07:08 kdy1

I've not dig into spack yet... it's a bundle tool right?

jest transformer must transform files one by one, so I guess spack not suitable to use in jest

Brooooooklyn avatar Aug 13 '20 08:08 Brooooooklyn

Hmm...

If ts-jest handles custom enum by using typescript compiler, it can be done.

Inlining only const enum in a file-by-file manner is also possible, but it requires reading dependency file anyway. (tsc will also do it, because logically it is required)

kdy1 avatar Aug 13 '20 08:08 kdy1

any updates on this ?

mehrangta avatar Jul 29 '21 10:07 mehrangta

duplicate of #1584?

Austaras avatar Jul 29 '21 10:07 Austaras

@Austaras #1584 is a better name in the point of view of implementors, but users will search it by "const enum" and will typically come here.

@mehrangta No, because this is a huge change which cannot be reverted.

kdy1 avatar Jul 29 '21 10:07 kdy1

As babel now supports const enum, I'll add this to the radar.

kdy1 avatar Aug 04 '21 22:08 kdy1

What's your opinion on babel's current implementation?

Austaras avatar Aug 09 '21 11:08 Austaras

@Austaras It seems like a proper decision, considering the fact that babel only works on one file at a time. I think matching the behavior of tsc is the best way to go.

kdy1 avatar Aug 09 '21 14:08 kdy1

Any updates? 😅🙄

leonardssh avatar Aug 22 '21 17:08 leonardssh

Hey, thanks for the great work on above package. I am facing similar issue with enums, any update on this?

akshayr20 avatar Oct 04 '21 04:10 akshayr20

@kdy1 Given that const enum is a bit of an outlier but very useful for library developers who want to keep bundles small, would a way forward be to pass const enum definitions to swc as a config. That should simplify the implementation in swc and it can easily be deprecated if a better solution is implemented. Maintaining the swc-specific const enum definitions would be worth the effort to those who use them.

jhsware avatar Nov 05 '21 08:11 jhsware

We could have a simple workaround to compile const enum to const object to keep bundle smaller:

export const enum Foo {
  A,
  B,
  C,
}

into

export const Foo = {
  A: 0,
  B: 1,
  C: 2
}

what do you think? @kdy1

Brooooooklyn avatar Nov 05 '21 10:11 Brooooooklyn

Sounds like a good idea, I'll see if I can fix this with a new version.

kdy1 avatar Nov 05 '21 11:11 kdy1

@kdy1 @Brooooooklyn Here is an example of const enum being used in Infernojs to keep the generated bundle size small and performance high, but still type safe and readable. Const enum defs:

https://github.com/infernojs/inferno/blob/2b2757387fbaa1f7021b0997d4cbafa488d396a7/packages/inferno-vnode-flags/src/index.ts

Use in code:

https://github.com/infernojs/inferno/blob/2b2757387fbaa1f7021b0997d4cbafa488d396a7/packages/inferno-hydrate/src/index.ts#L19

When this is transpiled, the const enum references are replaced for performance which makes it super fast.

if (x === Foo.A) ... transpiles to if (x === 0) ...

jhsware avatar Nov 05 '21 12:11 jhsware

I'm still waiting for this feature. 😅 (I know this is difficult to get done)

leonardssh avatar Feb 04 '22 00:02 leonardssh

@kdy1 why not do what tsc does with preseveConstEnums set to true?

https://www.typescriptlang.org/tsconfig#preserveConstEnums

This will basically treat the const enum as an enum, emit the runtime representation of the latter.

matthewjh avatar Mar 16 '22 12:03 matthewjh

Meanwhile, here is a eslint rule to disallow const enum usage: https://www.npmjs.com/package/eslint-plugin-typescript-enum

dko-slapdash avatar Jul 12 '22 09:07 dko-slapdash