Дженерики
Основная цель разработки дженериков состоит в том, чтобы обеспечить значимые ограничения между членами, которые могут быть:
Экземпляр класса
Методы класса
Функциональный параметр
Возвращаемое значение функции
Мотивация и примеры
Вот простая реализация структуры данных «первым пришел - первым вышел», очереди в TypeScript
и JavaScript
.
В приведенном выше коде есть проблема: он позволяет добавлять в очередь данные любого типа, конечно, когда данные выталкиваются из очереди, они также могут быть любого типа. В приведенном ниже примере кажется, что можно добавить данные типа string
в очередь, но на практике это использование предполагает, что в очередь будет добавлен только тип number
.
Одно из решений (на самом деле это единственное решение, которое не поддерживает универсальные типы) - это создание специальных классов для этих ограничений, таких как быстрое создание очереди числовых типов:
Конечно, скорость также означает боль. Например, если вы хотите создать очередь из строк, вам придется снова немного изменить код. Один из способов, которым мы действительно хотим, заключается в том, что независимо от того, какой тип помещается в очередь, выдвигаемый тип совпадает с выдвигаемым типом. Это легко, когда вы используете дженерики:
Другой пример, который мы видели: reverse
функция, которая теперь предоставляет ограничения на параметры функции и возвращаемые значения:
В этом разделе вы узнали примеры использования дженериков в классах и функциях. Стоит добавить, что вы можете добавить универсальные элементы к функциям-методам, которые вы создаете:
Неправильные дженерики
Я видел, как разработчики используют дженерики только для взлома. Когда вы используете его, вы должны спросить себя: какие ограничения вы хотите использовать для его предоставления. Если вы не можете ответить правильно, вы можете использовать дженерики, такие как:
Здесь нет необходимости использовать дженерики, поскольку они используются только для позиции одного параметра. Возможно, лучше использовать:
Дизайн шаблона: удобный и универсальный
Рассмотрим следующую функцию:
В этом случае универсальный T
используется только в одном месте, он не обеспечивает ограничение T
между членами. Это эквивалентно утверждению типа, как это:
Дженерики, которые используются только один раз, не более безопасны, чем утверждение типа. Оба они обеспечивают удобство использования API.
Другой очевидный пример - функция загрузки возвращаемого значения json, которая возвращает Promise
любого из переданных вами типов:
Обратите внимание, что вам все еще нужно явно сообщить тип, который вам нужен, но подпись getJSON<T>
в config => Promise<T>
может сократить некоторые ваши ключевые шаги (вам не нужно сообщить возвращаемый тип loadUsers
, потому что его можно вытолкнуть):
Также возвращаемое значение с использованием Promise<T>
как функции намного лучше, чем некоторые альтернативы, такие как Promise<any>
.
Использование с axios
При нормальных обстоятельствах мы будем помещать формат данных бэкэнда в интерфейс отдельно:
Когда мы разделяем API на один модуль:
Затем мы записываем возвращаемый тип данных User
, который позволяет TypeScript выводить нужный нам тип:
Last updated
Was this helpful?