2

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 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.