На этой странице предполагается, что вы уже прочитали обзор использования Vue с TypeScript
Props
С использованием <script setup>
При использовании script setup макрос defineProps() поддерживает определение типов реквизита на основе его аргумента
Это называется «объявлением времени выполнения», поскольку переданный аргумент defineProps() будет использоваться в качестве propsпараметра времени выполнения.
Однако обычно проще определить свойства с чистыми типами через аргумент универсального типа
Это называется «объявлением на основе типа». Компилятор постарается сделать все возможное, чтобы определить эквивалентные параметры времени выполнения на основе аргумента типа. В этом случае наш второй пример компилируется с теми же параметрами времени выполнения, что и первый пример.
Вы можете использовать либо объявление на основе типа, либо объявление времени выполнения, но вы не можете использовать оба одновременно.
Мы также можем переместить типы реквизитов в отдельный интерфейс
Это также работает, если Props импортируется из внешнего источника. Эта функция требует, чтобы TypeScript был одноранговой зависимостью Vue
# Синтаксические ограничения
В версии 3.2 и ниже параметр универсального типа defineProps() ограничивался литералом типа или ссылкой на локальный интерфейс.
Это ограничение было устранено в версии 3.3. Последняя версия Vue поддерживает ссылки на импортированные и ограниченный набор сложных типов в позиции параметра типа. Однако, поскольку преобразование типа в среду выполнения по-прежнему основано на AST, некоторые сложные типы, требующие фактического анализа типов, например условные типы, не поддерживаются. Вы можете использовать условные типы для типа одного реквизита, но не для всего объекта реквизита.
Значения props по умолчанию
При использовании объявления на основе типа мы теряем возможность объявлять значения по умолчанию для реквизитов. Это можно решить с помощью withDefaults макроса компилятора:
Это будет скомпилировано с эквивалентными defaultпараметрами реквизита во время выполнения. Кроме того, withDefaults помощник обеспечивает проверку типов для значений по умолчанию и гарантирует, что в возвращаемом propsтипе удалены необязательные флаги для свойств, для которых объявлены значения по умолчанию.
# Без <script setup>
Если вы не используете script setup, необходимо использовать defineComponent() для включения вывода типа реквизита. Тип передаваемого объекта реквизита setup() выводится из этой propsопции
Сложные типы props
При объявлении на основе типа свойство может использовать сложный тип, как и любой другой тип:
Для объявления времени выполнения мы можем использовать PropType тип утилиты:
Это работает почти так же, если мы указываем опцию props напрямую:
Этот props параметр чаще используется с API-интерфейсом параметров, поэтому более подробные примеры вы найдете в руководстве по TypeScript с API-интерфейсом параметров. Методы, показанные в этих примерах, также применимы к объявлениям времени выполнения с использованием defineProps()
Ввод компонентов emits
В script setup функции emit также можно ввести тип, используя объявление времени выполнения ИЛИ объявление типа:
Аргумент типа может быть одним из следующих:
- Тип вызываемой функции, но записанный как литерал типа с помощью сигнатур вызовов. Он будет использоваться как тип возвращаемой emit функции.
- Литерал типа, где ключами являются имена событий, а значениями являются типы массивов/кортежей, представляющие дополнительные принятые параметры для события. В приведенном выше примере используются именованные кортежи, поэтому каждый аргумент может иметь явное имя.
Как мы видим, объявление типа дает нам гораздо более детальный контроль над ограничениями типов отправляемых событий.
Если не использовать script setup, defineComponent() можно определить разрешенные события для emit функции, представленной в контексте настройки:
Ввод текста ref()
Ссылки определяют тип по начальному значению:
Иногда нам может потребоваться указать сложные типы для внутреннего значения ссылки. Мы можем сделать это, используя Ref тип:
Или, передав общий аргумент при вызове, ref()чтобы переопределить вывод по умолчанию:
Если вы укажете аргумент универсального типа, но опустите начальное значение, результирующий тип будет типом объединения, который включает undefined
Ввод текста reactive()
reactive() также неявно выводит тип из своего аргумента:
Чтобы явно ввести reactive свойство, мы можем использовать интерфейсы:
Обратите внимание
Не рекомендуется использовать универсальный аргумент, reactive()поскольку возвращаемый тип, который обрабатывает развертывание вложенных ссылок, отличается от типа универсального аргумента.
Ввод текста computed()
computed() выводит его тип на основе возвращаемого значения метода получения:
Вы также можете указать явный тип с помощью универсального аргумента:
Ввод обработчиков событий
При работе с собственными событиями DOM может быть полезно правильно ввести аргумент, который мы передаем обработчику. Давайте посмотрим на этот пример:
Без аннотации типа eventаргумент будет неявно иметь тип any. Это также приведет к ошибке TS, если "strict": true или "noImplicitAny": true используются в tsconfig.json. Поэтому рекомендуется явно аннотировать аргументы обработчиков событий. Кроме того, вам может потребоваться использовать утверждения типа при доступе к свойствам event
Typing Provide / Inject
Обеспечение и внедрение обычно выполняются отдельными компонентами. Для правильного ввода введенных значений Vue предоставляет InjectionKey интерфейс, который является универсальным типом, расширяющим Symbol. Его можно использовать для синхронизации типа введенного значения между поставщиком и потребителем:
Рекомендуется поместить ключ внедрения в отдельный файл, чтобы его можно было импортировать в несколько компонентов.
При использовании ключей внедрения строки тип введенного значения будет unknown, и его необходимо явно объявить с помощью аргумента универсального типа:
Обратите внимание, что введенное значение по-прежнему может быть undefined, поскольку нет гарантии, что поставщик предоставит это значение во время выполнения.
Тип undefined можно удалить, указав значение по умолчанию:
Если вы уверены, что значение всегда предоставляется, вы также можете принудительно привести его:
Ссылки на шаблоны ввода
Ссылки на шаблоны должны создаваться с явным аргументом универсального типа и начальным значением null
Чтобы получить правильный интерфейс DOM, вы можете проверить такие страницы, как MDN
Обратите внимание, что для строгой безопасности типов необходимо использовать дополнительное связывание или защиту типов при доступе к el.value. Это связано с тем, что начальное значение ссылки действует null до тех пор, пока компонент не будет смонтирован, и его также можно установить, null если элемент, на который ссылается, размонтирован с помощью v-if
Ввод ссылок на шаблоны компонентов
Иногда вам может потребоваться аннотировать ссылку на шаблон дочернего компонента, чтобы вызвать его общедоступный метод. Например, у нас есть MyModal дочерний компонент с методом, открывающим модальное окно
Чтобы получить тип экземпляра MyModal, нам нужно сначала получить его тип через typeof, а затем использовать встроенную InstanceType утилиту TypeScript для извлечения типа его экземпляра:
Обратите внимание, что если вы хотите использовать эту технику в файлах TypeScript вместо Vue SFC, вам необходимо включить режим Takeover Mode Volar
В случаях, когда точный тип компонента недоступен или не важен, ComponentPublicInstance вместо него можно использовать. Сюда будут включены только те свойства, которые являются общими для всех компонентов, например $el