Skip to content

es3/es5 inheritance bug #33023

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
elderapo opened this issue Aug 22, 2019 · 8 comments
Closed

es3/es5 inheritance bug #33023

elderapo opened this issue Aug 22, 2019 · 8 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@elderapo
Copy link

TypeScript Version: all versions

Search Terms: es3 es5 inheritance bug

Code

class SomeClass extends Object {}

const instance = new SomeClass();

console.log(instance instanceof SomeClass);
console.log(instance instanceof Object);

Expected behavior:
For every compilation target desired output is:

true
true

Actual behavior:
If the compilation target is set to es3 or es5:

false
true

Playground Link: https://typescript-play.js.org/?target=1#code/MYGwhgzhAEDKD2BbApgYXFayAeAXZAdgCYwDyARgFbLC7QDeAvgFAD0r0okMCK63DFs2DwCEOvGgBeaAWQB3OEjQYIACgCUAbmbDREeCGQA6EPADmayQEsxuMAWDJ4AMyV9V2vWMMmzlmzsHJ1doCmpaDSA

@elderapo
Copy link
Author

Emitted code for es5:

"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var SomeClass = /** @class */ (function (_super) {
    __extends(SomeClass, _super);
    function SomeClass() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    return SomeClass;
}(Object));
var instance = new SomeClass();
console.log(instance instanceof SomeClass);
console.log(instance instanceof Object);

Changing 12th line from:

d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());

to

d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype);

fixes the issue but not exactly sure what new __() is supposed to do there.

Also, it's probably worth mentioning that I only managed to reproduce this bug when extending native Object.

@elderapo
Copy link
Author

Oh... I've seen that one before. I thought it was only the case when extending Error...

Any idea what is the point of new __() on 12th line? Without it above code works just fine. Also it seems to fix all the issues listed here.

@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Aug 22, 2019
@typescript-bot
Copy link
Collaborator

This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.

3 similar comments
@typescript-bot
Copy link
Collaborator

This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.

@typescript-bot
Copy link
Collaborator

This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.

@typescript-bot
Copy link
Collaborator

This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.

@ExE-Boss
Copy link
Contributor

new __() creates a new object with b.prototype as its prototype, which is necessary so that adding properties to d.prototype doesn't also add them to b.prototype.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

5 participants