64

I encountered new() in the official document here about generics.

Here is the code context:

function create<T>(c: { new(): T; } ): T { return new c(); } 

The above code is transpiled to the following JavaScript code:

function create(c) { return new c(); } 

new() is illegal syntax in JavaScript. What does it mean in TypeScript?

Furthermore, what does {new(): T; } mean? I know it must be a type, but how?

4
  • 2
    Possible duplicate of How does typescript interfaces with construct signatures work? Commented Sep 21, 2016 at 17:28
  • used in an interface or inline interface it describes signature of the constructor. Commented Sep 21, 2016 at 17:39
  • @toskv new() looks like a function invocation. Why it is the signature of the constructor? Commented Sep 21, 2016 at 17:44
  • in es5 the way you implement classes is by creating in instances of functions. that's just the way to do it new functionName(). Commented Sep 21, 2016 at 18:52

5 Answers 5

83

new() describes a constructor signature in typescript. What that means is that it describes the shape of the constructor. For instance take {new(): T; }. You are right it is a type. It is the type of a class whose constructor takes in no arguments. Consider the following examples

function create<T>(c: { new(): T; } ): T { return new c(); } 

What this means is that the function create takes an argument whose constructor takes no arguments and returns an instance of type T.

function create<T>(c: { new(a: number): T; } ): T 

What this would mean is that the create function takes an argument whose constructor accepts one number a and returns an instance of type T. Another way to explain it can be, the type of the following class

class Test { constructor(a: number){ } } 

would be {new(a: number): Test}

Sign up to request clarification or add additional context in comments.

10 Comments

maybe adding a class implementing them (and their transpilation to javascript) would help clear the problem.
After transpilation the type would have no existence since there is no concept of types in javascript and hence there would be no new(). There is no such thing as new() in javascript.. it is only in typescript
ofcourse there is new functionName() in javascript. you create a new instance of that function object. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Yes but there is no new(), there is new functionName() and new ClassName() but no new()
ah, that is right indeed. :) it's just typescript stuff
|
16

The new keyword is used to create an instance of a class, so in its simplest form:

class SimpleClass { } 

Would be constructed as follows:

let simpleClassInstance = new SimpleClass(); 

This is all well and good, but how do you create an instance of a generic class, i.e.:

class SimpleClassFactory< T > { static create( T ) { return new T(); // compile error could not find symbol T } } 

Would be used as follows:

let simpleClassInstance = SimpleClassFactory.create(SimpleClass); 

Here, we are attempting to use the class definition to create an instance of a class. This will generate a compile error.

So we need to refer to the type by its constructor signature:

class SimpleClassFactory< T > { static create( type: { new(): T ;} ) { return new type(); // succeeds } } 

Comments

2

What is new() => T?

Essentially it is a way to declare an "Object Type" in which you can then create an instance of said "Object Type" with.

Example

class MyClass { // ... } // Creates new object types that don't have arguments in their constructors function createObjectGivenObjectType<T>(ObjectType: new() => T): T { return new ObjectType(); } const myObject: MyClass = createObjectGivenObjectType(MyClass); 

Simplify new() => T

I personally find it confusing when I see new() => T in a codebase. To simplify the problem, and to allow for better code readability, abstract this idea away from other devs by declaring a new type in your codebase called Type:

export type Type<T> = new (...args: any[]) => T; 

Then the above createObjectGivenObjectType function can become:

// Then this reads as: ObjectType is a type of T function createObjectGivenObjectType<T>(ObjectType: Type<T>): T { return new ObjectType(); } 

Furthermore, what does { new(): T; } mean? I know it must be a type, but how?

From the example you give it appears to be a more obtuse way of passing in an "Object Type" to a function.

Some examples that all do the same thing:

function create<T>(c: { new(): T; }): T { return new c(); } create(X); function create<T>(c: new() => T): T { return new c(); } create(X); function create<T>(c: Type<T>): T { return new c(); } create(X); 

Comments

1

{new(): T } actually is a class type that is referred to as a constructor function. another syntax of representing a type as a constructor function is by using this syntax

new () => Type 

In the case of the create functions, an alias could be represented as

function create<T>(c: new () => T ): T { return new c(); } 

Constructor functions are generally helpful in typescript for creating class instances from factory functions. In the case of the factory function 'create' above, it accepts a class type whose constructor has no arguments "{new(): T; }" and returns an instance of the class "T".

Example:

class BeeKeeper { hasMask: boolean = true; } const newClass = create(BeeKeeper) console.log(newClass instanceof BeeKeeper) // Prints true 

constructor functions can also be represented as below in the case of a constructor function that accepts arguments

new (b: string) => T or {new(b: string): T } 

Comments

0

So in the documentation is mentions that the syntax is for "When creating factories in TypeScript using generics".

If you look at a larger example that they have:

class BeeKeeper { hasMask: boolean; } class ZooKeeper { nametag: string; } class Animal { numLegs: number; } class Bee extends Animal { keeper: BeeKeeper; } class Lion extends Animal { keeper: ZooKeeper; } function findKeeper<A extends Animal, K> (a: {new(): A; prototype: {keeper: K}}): K { return a.prototype.keeper; } findKeeper(Lion).nametag; // typechecks! a: {new(): A // is actually creating a new instance of the type A which is extending Animal. // it is necessary to refer to class types by their constructor functions 

1 Comment

still not clear. Can you give a simpler, not complex, example of new()? Thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.