简体   繁体   中英

What does new?() mean in typescript?

I have this code snippet in typescript playground:

interface IFoo {
    new?():string;

}

class Foo implements IFoo {
    new() {
     return 'sss'; 
    }

}

I have to put "?" in the interface method new, otherwise it will show compile error. I cannot figure out why.

Update: the original question is not a good way of using new, so I post a more realistic and practical way of using the above mentioned new():

interface IUser {
  id: number;
  name: string;
}

interface UserConstructable {
  new (id: number, name: string, ...keys: any[]): IUser;
}

class User implements IUser {
  constructor(public id: number, public name: string) {

  }
}

class Employee implements IUser {
  constructor(public id: number, public name: string, 
    private manager: string) {

  }
}


class UserFactory {
   private static _idx: number = 0;
   static makeUser(n: UserConstructable): IUser {
      let newId = UserFactory._idx++;

      return new n(newId, 'user-' + newId, 'manager-' + newId);
   } 
}

console.log(UserFactory.makeUser(User));
console.log(UserFactory.makeUser(User));
console.log(UserFactory.makeUser(Employee));

Let's break this into a couple of parts... I know that you already know some of this, but I'm trying to be complete.

1..2.3..4
new?():string;
  1. In this specific context, new is not a keyword, it is just a method name... due to the next item in this list...

  2. The ? makes this optional (ie you can implement the interface without implementing this method).

  3. The () means new is a method.

  4. The return type is a string

Example

class Foo implements IFoo {
    new() {
        return 'sss'; 
    }
}

class Bar implements IFoo {
    // Because new is optional, you don't have to implement it
}

If you omit the ? , then you are using new as a keyword - but TypeScript interprets the code in your example as a simple method.

On the whole, though, I'd avoid naming a member with something that is known as a reserved word.

In javascript, functions are objects, and thus typescript interfaces should also be able to match functions. This is why we get those weird interfaces.

interface SomeFunc {
  (key: string): boolean;
  (key: number): boolean;
}

That interface will only match a function that accepts either a string or a number and returns a boolean.

Now consider the case of constructor functions (ie classes in ES5-).

function MyClass() {
  this.prop = value;
}
let myClass = new MyClass;

We need a way to create an interface that matches the signature of MyClass function. This is where we get the new function in interfaces.

interface IFoo {
  new (key: string): {key:string};
}

function someFunction(key: string) { // doesn't match IFoo
  return {key};
}

var someObject = { // still doesn't match IFoo
  new(key: string) { 
    return {key};
  },
};

function MyClass(key: string) { // matches IFoo! must be called like `new MyClass()`
  this.key = key;
}

so you can say that the signature of function new must match the signature of the class constructor.

interface IFoo {
  new(key: string): {};
}
class Foo implements IFoo { // works ok
  constructor(key: string) { // you can't return anything
  }
}

I think what you wanted to do is this:

interface IFoo {
  new: () => string;
}

ie IFoo should have a property called new which is a function that returns a string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM