Что нового() в Typescript?
Я встретил new()
в официальном документе здесь о дженериках.
Вот контекст кода:
function create<T>(c: { new(): T; } ): T {
return new c();
}
Приведенный выше код переносится в следующий код JavaScript:
function create(c) {
return new c();
}
new()
- это недопустимый синтаксис в JavaScript. Что это значит в TypeScript?
Кроме того, что делает {new(): T; }
{new(): T; }
значит? Я знаю, что это должен быть тип, но как?
Ответы
Ответ 1
new()
описывает сигнатуру конструктора в машинописи. Это означает, что он описывает форму конструктора. Например, возьмите {new(): T; }
{new(): T; }
Вы правы, это тип. Это тип класса, конструктор которого не имеет аргументов. Рассмотрим следующие примеры
function create<T>(c: { new(): T; } ): T {
return new c();
}
Это означает, что функция create
принимает аргумент, конструктор которого не принимает аргументов, и возвращает экземпляр типа T
function create<T>(c: { new(a: number): T; } ): T
Это означает, что функция create принимает аргумент, конструктор которого принимает одно число a
и возвращает экземпляр типа T. Другой способ объяснить это может быть тип следующего класса
class Test {
constructor(a: number){
}
}
будет {new(a: number): Test}
Ответ 2
Новое ключевое слово используется для создания экземпляра класса, поэтому в нем простейшая форма:
class SimpleClass {
}
Будет построено следующим образом:
let simpleClassInstance = new SimpleClass();
Это все хорошо и хорошо, но как создать экземпляр универсального класса, например:
class SimpleClassFactory< T > {
static create( T ) {
return new T(); // compile error could not find symbol T
}
}
Будет использоваться следующим образом:
let simpleClassInstance = SimpleClassFactory.create(SimpleClass);
Здесь мы пытаемся использовать определение класса для создания экземпляра класса. Это приведет к ошибке компиляции.
Поэтому нам нужно обратиться к типу по его подписи конструктора:
class SimpleClassFactory< T > {
static create( type: { new(): T ;} ) {
return new type(); // succeeds
}
}
Ответ 3
Поэтому в документации упоминается, что синтаксис предназначен для "При создании заводов в TypeScript с использованием дженериков".
Если вы посмотрите на больший пример, который у них есть:
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