Почти все знают, что такое декораторы TypeScript, есть масса статей на эту тему. Я не буду тратить ваше время на описание того, что они из себя представляют и почему вы должны их использовать (или не использовать). В этой статье мы поговорим о некоторых продвинутых практиках декораторов TypeScript. Если вы не знакомы с декораторами TypeScript, сначала ознакомьтесь с официальной документацией.

Начнем с декораторов свойств. Вот определение типа PropertyDecorator из библиотеки TypeScript.

Декоратор свойства — это просто функция, которая получает объект, содержащий свойство и ключ свойства.

Давайте напишем простой декоратор свойств, который выполняет некоторую регистрацию.

Этот декоратор записывает в экземпляр консоли и ключ поля. Вроде все в порядке, но Object не предоставляет никакой информации о типе экземпляра. Например, попробуем установить какое-нибудь свойство в декораторе:

Ошибка была ожидаемой, Object ничего не знает о a или других полях. Попробуем явно определить тип obj:

Теперь код правильный, и мы можем установить поле a. Но что, если мы попытаемся использовать этот декоратор для класса без поля .

Мы добавили этот декоратор в класс A, который не реализует интерфейс WithA и TypeScript не показывает никаких ошибок. Почему???!!! Мы любим TypeScript для проверки типов, чтобы избежать неожиданного поведения во время выполнения. Но в данном случае TypeScript даже не предупредил нас о возможной ошибке.

Как это решить? Возможно, мы можем создать собственное определение типа для PropertyDecorator, которое в этом случае выдаст ошибку:

Это то же самое, что и оригинальный PropertyDecorator, мы просто добавили проверку того, что Tрасширяет Base. Типом по умолчанию для Base является любой, поскольку ограничение типа не всегда необходимо. Также мы назвали его TPPropertyDecorator, чтобы избежать конфликта с типом bultin PropertyDecorator. Давайте проверим, как это работает на предыдущем примере:

У нас ошибка типа! Теперь он работает так, как ожидалось. Попробуем исправить:

Все работает так, как ожидалось. TPPropertyDecorator может проверить, где он использовался, и выдать ошибку времени компиляции, если класс не удовлетворяет его требованиям.

Вывод: в этой статье мы узнали о некоторых крайних случаях использования определения типа bultin PropertyDecorator и о том, как их избежать. Я надеюсь, что эта статья была полезной.

Увидимся в следующий раз, servus!