microsoft / microsoft/TypeScript

Make 'new.target' emit more precautions

Open
#15,474 11 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Awaiting More Feedback Suggestion
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
132

Description

I noticed that the polyfill for new.target ...

class Foo {
    constructor() {
        if (new.target)
            alert("Good.");
        else
            alert("Bad!");
    }
}

... outputs to this:

var Foo = (function () {
    function Foo() {
        var _newTarget = this.constructor;
        if (_newTarget)
            alert("Good.");
        else
            alert("Bad!");
    }
    return Foo;
}());

That seems dangerous to me, since this is always a true condition for older browsers that don't yet support new.target. Does it not make more sense to create an output such as this?:

var Foo = (function () {
    function Foo() {
        var _newTarget = this && this.constructor !== Window ? this.constructor : void 0;
                         /* (have to check 'this' also, in case of strict mode) */
        if (_newTarget)
            alert("Good.");
        else
            alert("Bad!");
    }
    return Foo;
}());

The following code fails to work as expected in Chrome v56.0.2924.87 (output is "Good." in call cases):

class $Foo {
    constructor() {
        if (new.target)
            alert("Good.");
        else
            alert("Bad!");
    }
}

type FooConstructor = typeof $Foo;

interface CallableFoo extends FooConstructor { (): $Foo; }

new $Foo(); // ok
var Foo: CallableFoo = <any>Foo;
Foo(); // ok? :/

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked TypeScript Playground repro and compare the emitted JavaScript for new $Foo() and Foo(). Trace the compiler's new.target lowering; done means the generated output preserves the different results for constructor and ordinary calls without treating both as truthy.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.