TypeScript: tslib.__extends called on undefined prototype

TypeScript Version: 2.2.1

Code To make things simple, here’s a repo to easily reproduce this: https://github.com/jsayol/typescript-issue-14734

$ git clone https://github.com/jsayol/typescript-issue-14734.git
$ cd typescript-issue-14734
$ npm install
$ npm run build

And load index.html in the browser.

a.ts:
import { B } from './b';

export class A {
  constructor(public prop: string) {
  }

  b(): B {
    return new B(this.prop, 123);
  }

  log() {
    console.log(`Prop: ${this.prop}`);
  }
}
b.ts
import { A } from './a';

export class B extends A {
  constructor(prop: string, public otherStuff: number) {
    super(`B ${prop}`);
  }
}
index.ts
import { A } from './a';
import { B } from './b';

const a = new A('hello');
const b: B = a.b();
b.log();

Expected behavior: Seeing “B hello” logged in the console.

For reference, putting all the code in a single file generates the correct output:

class A {
  constructor(public prop: string) {
  }

  b(): B {
    return new B(this.prop, 123);
  }

  log() {
    console.log(`Prop: ${this.prop}`);
  }
}

class B extends A {
  constructor(prop: string, public otherStuff: number) {
    super(`B ${prop}`);
  }
}

const a = new A('hello');
const b: B = a.b();
b.log();

Actual behavior:

tslib.es6.js:22 Uncaught TypeError: Object prototype may only be an Object or null: undefined
    at setPrototypeOf (<anonymous>)
    at Object.__extends [as a] (tslib.es6.js:22)
    at b.js:4
    at Object.__webpack_exports__.a (b.js:11)
    at __webpack_require__ (bootstrap 4672cf4…:19)
    at Object.defineProperty.value (bootstrap 4672cf4…:65)
    at __webpack_require__ (bootstrap 4672cf4…:19)
    at Object.<anonymous> (bundle.umd.js:108)
    at __webpack_require__ (bootstrap 4672cf4…:19)
    at Object.<anonymous> (bundle.umd.js:321)

This is the generated b.js, where the problem is:

import * as tslib_1 from "tslib";
import { A } from './a';
var B = (function (_super) {
    tslib_1.__extends(B, _super); // <--- Exception thrown here. "B" is undefined.
    function B(prop, otherStuff) {
        var _this = _super.call(this, "B " + prop) || this;
        _this.otherStuff = otherStuff;
        return _this;
    }
    return B;
}(A));
export { B };
//# sourceMappingURL=b.js.map

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 15 (5 by maintainers)

Commits related to this issue

Most upvoted comments

You are dealing with a circular dependency. TypeScript can statically identify the shape of everything, therefore it is fine, but it seems WebPack (you module loader of choice) is not resolving the circular dependency effectively at runtime. I suspect that WebPack is attempting to instantiate module B before module A is ready, therefore module B can be loaded properly.

When they are in the same module, B isn’t technically required by A until a certain method is called, therefore everything is resolved fine.

You are giving one line of code and saying how do I fix it? when you have even indicated what the problem is. The code you are quoting doesn’t even reference the code at the top of this issue.

You should be asking “how do I” questions on Gitter or StackOverflow, providing an appropriate level of information on what the problem is.

Thanks for your imput @cvsguimaraes. In the end it all came down to the fact that TypeScript assumes that module imports do not have side effects.

See here for more info: https://github.com/webpack/webpack/issues/4520#issuecomment-288228218