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;
In this specific context, new
is not a keyword, it is just a method name... due to the next item in this list...
The ?
makes this optional (ie you can implement the interface without implementing this method).
The ()
means new
is a method.
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.