Search code examples
typescript

How to prevent TypeScript from stripping unassigned static class fields


If I use the following JavaScript code:

class test {
    static 'a-a';
    static 'b-b';
    static 'c-c';
  }
console.log(Object.keys(test))
// output (chrome console): ['a-a', 'b-b', 'c-c']

I can, at runtime, enumerate the static fields.

In TypeScript, however, this does not work (playground):

 class test {
    static 'a-a': unknown;
    static 'b-b': unknown;
    static 'c-c': unknown;
  }
console.log(Object.keys(test))

generates this JavaScript which misses the static fields:

"use strict";
class test {
}
console.log(Object.keys(test));
// output (chrome console): []

I need the runtime enumeration. Why is it removed?

What can I do to change that?

I tried all imaginable compiler options but found nothing that helped.


Solution

  • If you want TypeScript to emit class fields, you need to --target a version of JavaScript that supports them. Public class fields were introduced in ES2022.

    Additionally, you'll probably want to enable the --useDefineForClassFields compiler option, because that option ensures that TypeScript class fields and JavaScript class fields have the same behavior. According to the documentation, this option is automatically enabled for targets of ES2022 or later. But it doesn't hurt to explicitly enable it, just to be on the safe side.

    That means you need something like tsc --target es2022 --useDefineForClassFields ⋯ or the equivalent tsconfig.json settings.

    Playground link to code