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

Support 'new.target' meta object #2551

Closed
DanielRosenwasser opened this issue Mar 30, 2015 · 4 comments
Closed

Support 'new.target' meta object #2551

DanielRosenwasser opened this issue Mar 30, 2015 · 4 comments
Assignees
Labels
Committed The team has roadmapped this issue ES6 Relates to the ES6 Spec Fixed A PR has been merged for this issue Suggestion An idea for TypeScript

Comments

@DanielRosenwasser
Copy link
Member

There isn't a lot in the current ES6 spec draft, but it seems to indicate the constructor object that is in the process of being new'd at runtime.

@DanielRosenwasser DanielRosenwasser added Bug A bug in TypeScript ES6 Relates to the ES6 Spec labels Mar 30, 2015
@rbuckton
Copy link
Member

rbuckton commented Apr 1, 2015

We also need to update es6.d.ts for Reflect.construct which has the signature:

export function construct(target: any, argArray: any[], newTarget?: any): any;

Where newTarget is the value for new.target.

@mhegazy
Copy link
Contributor

mhegazy commented May 6, 2016

See relevant down-level emit suggestions in #8494

@kitsonk
Copy link
Contributor

kitsonk commented May 6, 2016

For completeness I will just copy them here:

Given:

function Foo() {
  console.log(new.target);
}

Foo(); // logs undefined
new Foo(); // logs Foo

The downlevel emit could be:

function Foo() {
  var _newTarget = this === (typeof window === 'undefined' ? global : window) ? undefined : this && this.constructor;
  console.log(_newTarget);
}

Foo(); // logs undefined
new Foo(); // logs Foo

When 'use strict'; is used, then this will be undefined anyways and the emit could simply be:

'use strict';

function Foo() {
  var _newTarget = this && this.constructor;
  console.log(_newTarget);
}

Foo();  // logs undefined
new Foo(); // logs Foo
@ghost
Copy link

ghost commented Nov 20, 2016

Just happened across this thread while looking at TS support for 'new.target'.

For use case of importing a function such as the Foo example above when such function is exported from, say, a CommonJS module, the immediately preceding comment re "When 'use strict'; is used, then 'this' will be undefined anyways and the emit could simply be ..." is not valid under all circumstances.

It is only valid in the use case whence Foo is invoked as a top-level function (either via new or normal function call) in the same source file.

When otherwise invoked as an imported function/constructor combo, it depends on whether the reference to Foo is obtained from a top-level variable (case 1) or via an import member in which case the reference is possibly, depending on codegen, obtained by a property access (case 2), i.e.

import { Foo } from "foo";

// case 1:
const Foo = foo.Foo;
Foo();
new Foo();

// case 2:
foo.Foo();
new foo.Foo();

For the moment, I'm going with this method in my code albeit correct though not completely generic (since have to type === functionname).

"use strict";
function Foo() {
  // simulate if (!new.target) with following line ...
  if (!this || this.constructor !== Foo) {
    console.log("Foo called without new");
  }

  else {
    console.log("Foo instantiated with new");
  }
}

exports.Foo = Foo;
@mhegazy mhegazy added Suggestion An idea for TypeScript Committed The team has roadmapped this issue and removed Bug A bug in TypeScript labels Dec 23, 2016
@mhegazy mhegazy added the Fixed A PR has been merged for this issue label Dec 28, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Committed The team has roadmapped this issue ES6 Relates to the ES6 Spec Fixed A PR has been merged for this issue Suggestion An idea for TypeScript
5 participants