Что нового() в 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