Skip to content

es3/es5 inheritance bug #33023

New issue

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

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

Already on GitHub? # 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.

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

No branches or pull requests

5 participants