Для того чтобы затипизировать декорируемый класс в TypeScript, мы можем использовать параметр T
в качестве обобщения (generic) для класса и указать тип этого обобщения при его декларации.
Декораторы в TypeScript - это функции, которые могут принимать различные аргументы и возвращать новый класс или функцию. Чтобы типизировать декорируемый класс, мы можем использовать обобщение на самом декораторе.
Давайте рассмотрим пример. У нас есть класс Person
с двумя свойствами - name
и age
. Мы хотим добавить декоратор log
к этому классу, который будет выводить в консоль информацию о создании нового объекта класса Person
.
function log<T extends { new (...args: any[]): {} }>(constructor: T) { return class extends constructor { constructor(...args: any[]) { super(...args); console.log(`New instance of ${constructor.name} created`); } }; } @log class Person { name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } } const person = new Person("John Doe", 25); // New instance of Person created console.log(person.name); // John Doe console.log(person.age); // 25
В приведенном выше примере мы определили декоратор log
, который принимает класс constructor
и возвращает новый класс, наследующийся от constructor
. В конструкторе нового класса мы вызываем super(...args)
для передачи аргументов конструктору оригинального класса.
Затем мы использовали декоратор log
для класса Person
. Теперь, при каждом создании нового экземпляра класса Person
, будет выводиться сообщение в консоль.
Обобщение <T extends { new (...args: any[]): {} }>
означает, что T
должен быть классом, у которого есть конструктор с любым количеством аргументов и не имеющим возвращаемого значения (или с возвращаемым значением типа {}
). Это позволяет нам использовать декоратор для любого класса, удовлетворяющего этим требованиям.
Таким образом, мы можем затипизировать декорируемый класс, используя обобщение в декораторе, и добавить кастомную логику в декоратор для дополнительной функциональности класса.