Skip to content

Ensure functions that have prototype properties assigned by Object.defineProperty get marked as classes - #34577

Merged
Andrew Branch (andrewbranch) merged 2 commits into
microsoft:masterfrom
andrewbranch:bug/34481-real
Oct 18, 2019
Merged

Andrew Branch (andrewbranch) merged 2 commits into
microsoft:masterfrom
andrewbranch:bug/34481-real

Conversation

@andrewbranch

Copy link
Copy Markdown
Member

Fixes #34481

Various JS constructs indicate to the binder that a function is actually a constructor:

  • Assigning to this inside the body
  • The /** @constructor */ JSDoc tag
  • Assigning to its prototype or prototype properties

A missing one was defining a prototype property via Object.defineProperty. So if you have the code

function Graphic() {
}

Object.defineProperty(Graphic.prototype, "instance", {
  get: function() {
    return this;
  }
});

The Object.defineProperty to the prototype is the sole indicator that Graphic is a constructor, but it was being missed, so the symbol Graphic was not marked as a class. However, when the checker tries to get the type of this, it rightly assumes that Graphic must be a class, and hence the crash.


It’s also notable that the provided repro had something like this:

function Graphic() {
  Object.defineProperty(this, "_inlineContent", { value: 3 });
}

which we don’t recognize as a bindable declaration onto Graphic at all—if we did, this bug would have remained undiscovered. Similarly, if the original code had any assignment to this, or any property assignment to Graphic.prototype, or used the JSDoc /** @constructor */ tag, the crash wouldn‘t have occurred because a different declaration would have marked Graphic as class-like.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot read property 'flags' of undefined TypeError when running tsc using 3.7.0-beta

3 participants