typescript-go icon indicating copy to clipboard operation
typescript-go copied to clipboard

Add {}/class-expression expandos

Open sandersn opened this issue 7 months ago • 0 comments

This PR adds support for expando properties on {} and class expressions in Javascript. It also adds support for expandos on expandos in Javascript:

var o = {}
o.C = class { // expando on o
  constructor() {
    this.o = {}
    this.o.p = 12 // expando on this.o
  }
}
o.C.x = 13 // expando on o.C

It also works with element accesses as well as property accesses.

Implementation notes

  • The PR, unfortunately, brings back some of the complexity that the binder uses to detect these different patterns. But it's still nothing like the checks in Strada.
  • I discovered that Strada's thisParentContainer tracking was not complete, so it relies on getThisContainer, which isn't safe to use in the binder because not all parent pointers are set. I added a specific ContainerFlags for this, and the resulting code should be simpler and safer.
  • Checking of {} expandos is different because the exports are on the object literal, not the declaring variable. The binding is now consistent between {}, class, function expressions, and the checker code to support the old way would be at least as bad.
  • The code to avoid type checking circularity for expando-{} means that those expando properties don't widen. I'll return to this later.
  • While adding the code to contextually type expando properties when there's a type annotation for the container, I made the code more like the Strada original.

The binder diff is a lot easier to read with whitespace ignored since I pulled out some code into a separate function.

sandersn avatar May 20 '25 17:05 sandersn