How to compile TypeScript classes with @babel/preset-typescript?

2.3k Views Asked by At

I'm trying to compile a library of TypeScript classes to ES5 by using a combination of @babel/preset-typescript and @babel/env. Without any plugins, it leads to a compilation error:

SyntaxError: C:\projects\time\git\core\main\src\LocalDate.ts: Missing class properties transform.
  35 | class LocalDate {
  36 |
> 37 |  private _weekBasedYear: number = null;
     |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  38 |
  39 |  private constructor(readonly nativeUtc: Date) {
  40 |  }

And here I'm stuck. In the official documentation, there's no reference to a recommended class properties transformation plugin. I tried to use @babel/plugin-proposal-class-properties, as it is recommended for JS, but it doesn't seem to be compatible with TypeScript. For example, when I compile the following pair of classes:

abstract class ClassA {

    abstract readonly value: number;
}

export class ClassB extends ClassA {

    get value() {
        return 1;
    }
}

export const B = new ClassB();

It produces the following JS code:

var ClassA = function ClassA() {
  _classCallCheck(this, ClassA);

  _defineProperty(this, "value", void 0);
};

var ClassB = /*#__PURE__*/function (_ClassA) {
  _inherits(ClassB, _ClassA);

  function ClassB() {
    _classCallCheck(this, ClassB);

    return _possibleConstructorReturn(this, _getPrototypeOf(ClassB).apply(this, arguments));
  }

  _createClass(ClassB, [{
    key: "value",
    get: function get() {
      return 1;
    }
  }]);

  return ClassB;
}(ClassA);

exports.ClassB = ClassB;
var B = new ClassB();
exports.B = B;

Which results in B.value to be undefined instead of 1.

I can't compile my TypeScript directly to JS, because I use ES6 API, and TypeScript compiler refuses to compile its usages for me.

src/Zone.ts(51,14): error TS2339: Property 'isFinite' does not exist on type 'NumberConstructor'.
src/Zone.ts(58,10): error TS2339: Property 'startsWith' does not exist on type 'string'.
src/Zone.ts(143,15): error TS2339: Property 'isFinite' does not exist on type 'NumberConstructor'.

I expect the library user to attach a suitable polyfill to ensure availability of all this API, but I don't know a way to explain this to the TypeScript compiler.

My .babelrc:

{
  "plugins": [
    "@babel/plugin-proposal-class-properties"
  ],
  "presets": [
    [
      "@babel/env",
      {
        "targets": {
          "browsers": [
            "last 2 versions",
            "IE >= 11"
          ]
        }
      }
    ],
    "@babel/preset-typescript"
  ],
  "parserOpts": {
    "strictMode": true
  },
  "sourceMaps": "inline"
}

Compilation command:

node_modules/.bin/babel --extensions ".ts" src --out-dir dist

What is the correct way to compile TypeScript classes to ES5 with Babel?

1

There are 1 best solutions below

0
On BEST ANSWER

I fixed the issue by compiling the project in two steps:

node_modules/.bin/tsc
node_modules/.bin/babel --out-dir dist dist-tsc

TypeScript should be configured to compile into ES6 or higher to make sure that the CommonJS module boilerplate doesn't get applied twice.

With that said, I have no clue what @babel/preset-typescript was created for.