TypeScript типы

Naive UI — это компонентная библиотека для Vue 3, разработанная с учётом гибкости и кастомизации. Одним из ключевых аспектов работы с Naive UI в TypeScript является корректное использование типов, что позволяет не только повысить надёжность кода, но и значительно улучшить автодополнение в IDE.

Основные принципы типизации

В Naive UI все компоненты строго типизированы. Это означает, что каждая пропса, событие и слот имеют собственный интерфейс или тип, который можно импортировать и использовать. Типы обычно предоставляются через глобальные декларации, а также через generics, что особенно полезно для компонентов с динамическими данными.

Пример простого использования типов пропсов:

import { NButton, ButtonProps } from 'naive-ui'

const props: ButtonProps = {
  type: 'primary',
  size: 'medium',
  disabled: false
}

Здесь ButtonProps описывает все доступные свойства кнопки, включая допустимые значения type и size. Такой подход исключает ошибки при передаче некорректных значений.

Generic-компоненты и их типизация

Многие компоненты Naive UI используют generics для более гибкой работы с типами данных. Особенно это актуально для компонентов, работающих с таблицами, списками и формами.

Пример: NDataTable с generics

import { NDataTable } from 'naive-ui'

interface User {
  id: number
  name: string
  email: string
}

const columns = [
  {
    title: 'ID',
    key: 'id'
  },
  {
    title: 'Имя',
    key: 'name'
  },
  {
    title: 'Email',
    key: 'email'
  }
]

const data: User[] = [
  { id: 1, name: 'Иван', email: 'ivan@example.com' },
  { id: 2, name: 'Мария', email: 'maria@example.com' }
]

<NDataTable<User> :columns="columns" :data="data" />

Использование generics позволяет TypeScript проверять типы данных в таблице и предотвращает ошибки при доступе к полям, которых нет в интерфейсе User.

Типизация событий

Компоненты Naive UI активно используют событийную модель Vue, и каждый компонент имеет типизированные события. Для кнопки NButton можно указать тип события click:

const handleClick: (e: MouseEvent) => void = (e) => {
  console.log('Клик по кнопке', e)
}

Для более сложных компонентов, таких как NDataTable или NForm, события часто включают объект данных. В этих случаях тип события указывается через интерфейсы компонентов или generics.

Работа с слотами

Naive UI поддерживает слот-компоненты, которые также могут быть типизированы. Например, в NSelect можно определить тип значения через generic:

import { NSelect } from 'naive-ui'

interface Option {
  label: string
  value: string
}

const options: Option[] = [
  { label: 'Красный', value: 'red' },
  { label: 'Синий', value: 'blue' }
]

<NSelect<Option> :options="options" v-model:value="selectedColor">
  <template #option="{ option }">
    <span>{{ option.label }}</span>
  </template>
</NSelect>

С помощью generic <Option> TypeScript гарантирует, что option.value всегда будет строкой, как указано в интерфейсе Option.

Типы для утилит и функций

Naive UI предоставляет вспомогательные утилиты, такие как useDialog, useMessage и useNotification. Все они имеют свои типы, которые позволяют точно указывать параметры и возвращаемые значения.

Пример для useDialog:

import { useDialog, DialogApiInjection } from 'naive-ui'

const dialog: DialogApiInjection = useDialog()

dialog.info({
  title: 'Информация',
  content: 'Сообщение для пользователя',
  positiveText: 'Ок'
})

Тип DialogApiInjection описывает все методы, доступные для работы с диалогами, включая info, warning, error и success. Это предотвращает случайное использование несуществующих методов.

Пользовательские типы для кастомизации

Для сложных интерфейсов часто необходимо создавать собственные типы, расширяющие стандартные. Например, при работе с NTable можно создать интерфейс для колонки с дополнительными параметрами:

import { DataTableColumn } from 'naive-ui'

interface CustomColumn<T> extends DataTableColumn<T> {
  sortable?: boolean
  filterable?: boolean
}

const columns: CustomColumn<User>[] = [
  { title: 'Имя', key: 'name', sortable: true },
  { title: 'Email', key: 'email', filterable: true }
]

Расширение типов позволяет сохранять преимущества автодополнения и строгой типизации, одновременно добавляя свои поля.

Выводы по типизации

Строгая типизация в Naive UI через TypeScript обеспечивает:

  • Предотвращение ошибок на этапе компиляции
  • Улучшенное автодополнение и навигацию по коду
  • Возможность безопасной работы с generics, слотами и событиями
  • Лёгкость расширения стандартных интерфейсов для сложных сценариев

Корректная типизация — это основа стабильного и масштабируемого фронтенд-приложения с Naive UI, особенно при работе с большими наборами данных и динамическими интерфейсами.