Декораторы позволяют добавлять аннотации к объявлениям и членам классов.

В этой статье мы узнаем о декораторах TypeScript. Декораторы следуют структурному программному принципу проектирования с тем же названием Decorator и предоставляют гибкую альтернативу подклассам для расширения функциональности.

Чтобы узнать больше о расширенных функциях TypeScript, ознакомьтесь с другими моими статьями. Вот обзор:



Декоратор

Шаблон structural Decorator очень эффективен и помогает нам предотвратить взрыв подклассов.

Целью шаблона Decorator является динамическое возложение дополнительной ответственности на объект и предоставление гибкой альтернативы созданию подклассов для расширения функциональности.

Паттерн Decorator широко используется и применим во многих случаях. Используйте шаблон, когда хотите:

  • создать большое количество подклассов. Иногда слишком много подклассов нецелесообразно и приводит к взрыву подклассов для поддержки каждой комбинации.
  • добавляйте обязанности к отдельным объектам динамически, не затрагивая другие объекты.
  • назначать дополнительное поведение объектам во время выполнения, не нарушая код, использующий эти объекты.


Декораторы машинописных текстов

Поскольку классы были представлены в Typescript и ES6, Typescript также хотел предоставить возможность поддержки аннотирования или изменения классов и членов классов с помощью декораторов.

Экспериментальная функция Typescript Decorator помогает нам украшать классы, методы, свойства, аксессоры и параметры. .

ПРИМЕЧАНИЕ Декораторы — это экспериментальная функция, которая может быть изменена в будущих версиях. — typescriptlang.org

Поскольку эта функция все еще является экспериментальной, нам сначала нужно включить ее, установив experimentalDecorators в true в пределах compilerOptions нашего tsconfig.json:

После того, как эта дополнительная настройка выполнена, мы можем создавать функции декоратора, которые можно использовать с @ перед ним.

Декораторы используют форму @expression, где expression должно оценивать функцию, которая будет вызываться во время выполнения с информацией о декорированном объявлении. — typescriptlang.org

Для начала, вот очень простой пример того, как создать функцию класса декоратора с именем logMessage, которая будет возвращать внутреннюю функцию, чтобы просто распечатать message после того, как объект объекта класс был создан.

Концепция наличия внутренней функции называется Фабрика декораторов и позволяет нам передавать параметры.

Чтобы настроить декораторы для работы по-разному в определенном сценарии, вы можете использовать концепцию под названием фабрика декораторов. — blog.logrocket.com/a-practical-guide-to-typescript-decorators

Теперь мы можем аннотировать любой класс, используя @logMessage('some Message'). Допустим, у нас есть класс User, и мы используем декоратор следующим образом:

Каждый раз, когда создается новый пользователь, мы будем видеть новое сообщение в консоли:

Вот игровая площадка Typescript из приведенного выше примера.

Это был очень простой пример. Но декораторы Typescript могут быть гораздо более полезными и сложными. Существует пять типов декораторов:

На мой взгляд, имеет смысл подробно рассмотреть каждый тип декораторов, потому что декораторы Typescript являются одной из наиболее сложных функций. В этой статье мы подробно рассмотрим декораторы классов и проверим код, чтобы усвоить эту функцию.

В следующих статьях мы рассмотрим другие типы декораторов, ссылки на которые я приведу здесь. Вы также можете просто подписаться на мои истории, чтобы не пропустить их.

Декораторы класса

Мы уже видели очень простой декоратор класса в нашем предыдущем примере. Давайте создадим более полезный, расширив конструктор нашего класса User. Мы хотим создать декоратор @admin, чтобы добавить некоторую функциональность в наш класс.

Вот как сейчас выглядит наш класс User:

Когда вы присоединяете функцию в качестве декоратора к классу, вы получаете конструктор класса в качестве первого параметра.

Если вы хотите переопределить или добавить новые свойства внутри класса, вы можете вернуть новый класс, расширяющий его конструктор:

Теперь давайте создадим наш декоратор @admin:

Теперь эту функцию можно оформить в нашем классе User, и она добавит onlyAdminsFunction к классу:

Обратите внимание, что вы можете легко добавить в класс несколько декораторов. Создание нового объекта класса User даст нам возможность вызывать onlyAdminsFunction():

Вот журналы:

Обратите внимание, что декоратор не меняет тип Typescript класса, поэтому мы видим следующую ошибку Typescript:

Свойство onlyAdminsFunction не существует для типа «Пользователь».

К сожалению, декораторы не могут влиять на структуру типа Typescript. Это означает, что мы должны работать с @ts-ignore здесь. Если здесь каким-то образом возможно добиться безопасности типов, пожалуйста, оставьте комментарий. Я хотел бы знать!

Вот игровая площадка Typescript для примера декоратора класса.

Вызов кода 💻

Мы уже узнали, как расширить наш класс User функцией onlyAdminsFunction(), аннотировав его с помощью нашего декоратора @admin.

Теперь мы хотим, чтобы наш класс User имел дополнительные свойства. Мы хотим, чтобы он имел атрибуты image и displayName, но не хотим изменять существующий класс. Вот почему мы создадим декоратор @displayable для динамического изменения нашего класса.

Новая функция декоратора displayable должна принимать два параметра и передавать их в свойства только что созданного объекта class. Обратите внимание, что декораторы не меняют тип TypeScript, поэтому можно работать с @ts-ignore для доступа к новым свойствам.

Код

Вот стартовый код, который содержит некоторые ошибки, которые можно исправить, создав правильную функцию-декоратор класса displayable.

Решение

Вот код решения для упражнения:

Сложность этого упражнения заключается в том, что нам нужно обернуть декоратор другой функцией, потому что мы передаем параметры в аннотацию @displayable. Это наша фабрика декораторов.

После этого мы можем просто расширить класс User, чтобы иметь дополнительные свойства displayName и image и присвоить значения параметрам функции.

Последние мысли

Надеюсь, вам понравилось читать эту статью. Я всегда рад ответить на вопросы и открыт для критики. Не стесняйтесь обращаться ко мне в любое время! Свяжитесь со мной через LinkedIn,подпишитесь на меня вTwitter или подпишитесь, чтобы получать мои истории по электронной почте.

Вот ссылка для неограниченного доступа ко всему контенту здесь, на Medium. Если вы зарегистрируетесь по этой ссылке, я заработаю небольшую сумму без каких-либо дополнительных затрат для вас.



об авторе

Я аналитик по разработке программного обеспечения в Accenture Song. Мы всегда ищем лучших разработчиков, поэтому не стесняйтесь обращаться к нам, если вы заинтересованы в том, чтобы присоединиться к нам!

Что меня больше всего движет, так это мое стремление создать что-то, что потенциально может быть полезным и изменить жизнь для других 🙌 Например, вы устали просматривать свою историю, чтобы найти информацию, которую вы видели несколько дней назад? Мое расширение Web Highlights для Chrome поможет вам и повысит вашу продуктивность, организовав ваши исследования структурированным и эффективным способом. Как и в книгах и статьях, выделяйте текст на любой веб-странице или в PDF-файле. Ваши основные моменты синхронизируются непосредственно с веб-приложением на web-highlights.com, где вы можете найти их где угодно.

Дальнейшее чтение





Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord . Заинтересованы в хакинге роста? Ознакомьтесь с разделом Схема.