Skip to content
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

Emitter: Static class property "name" causes TypeError due to Function.name being readonly #9778

Closed
about-code opened this issue Jul 17, 2016 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@about-code
Copy link
Contributor

about-code commented Jul 17, 2016

TypeScript Version: 1.8.10

Consider the following class definition with a static property name:

class Foo {
     static name() {
         return "Hello World";
     }
     constructor() {}
}

The TS emitter output for this is:

var Foo = (function () {
    function Foo() {
    }
    Foo.name = function () {
        return "Hello World";
    };
    return Foo;
}());

However, at least in Chrome and Firefox a function's name property is readonly for ordinary functions causing the assignment of the static function name to be ignored / causing a TypeError in strict mode.

The TS example above is also valid ES 2015 so I've tested it without transpilation in a current version of Chromium (v51.0.2704.79). Interestingly, while we can not change the name property of ordinary functions in Chromium we can still do the following for the constructor function once a static name property is present:

class Foo {
   static name() {
        return "Hello World";
   }
   constructor {}
}
Foo.name = "Hello World"
console.log(Foo.name); // logs "Hello World"

So the name property of the constructor function is no longer read-only. Based on this I assume Chromium internally does something like

Expected behavior:

var Foo = (function () {
    function Foo() {
    }
    Object.defineProperty(Foo, "name", { writable: true; });  // <= required for static class property *name*
    Foo.name = function () {
        return "Hello World";
    };
    return Foo;
}());

So a static class property name requires the name property to be made writable: true first. Unfortunately, Object.defineProperty is only available since ES 5 so static properties could become problematic for a compiler target of es3.

Therefore you might also want to note, that section 9.11.2 of ES2015 spec states that the ES interpreter must not set the name property, if a function does have an OwnProperty name. So the spec does seem to take custom values for Function.name into account which is why I consider a default configuration of writable: false for Function.name being problematic. It would certainly be better if browser vendors could agree here on making Function.name writable: true by default.

@about-code
Copy link
Contributor Author

about-code commented Jul 17, 2016

Note: it seems there have been some issues with

Object.defineProperty(Foo, "name", { writable: true; });

in the past with older versions of Chrome, due to older Chromes having set configurability of Function.name to false. See comment of @alexeagle and @rbuckton regarding issue #2836.

@mhegazy
Copy link
Contributor

mhegazy commented Jul 17, 2016

Duplicate of #442

@mhegazy mhegazy added the Duplicate An existing issue was already created label Jul 17, 2016
@mhegazy mhegazy closed this as completed Sep 20, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

2 participants