TypeScript ошибки

Naive UI — современная библиотека компонентов для Vue 3, полностью написанная на TypeScript, что обеспечивает строгую типизацию и высокую предсказуемость при разработке интерфейсов. При интеграции TypeScript с Naive UI часто возникают типовые ошибки, которые требуют внимательного анализа и понимания типовой системы Vue и самой библиотеки.


Ошибка Property '...' does not exist on type '...'

Эта ошибка возникает, когда TypeScript не может определить свойство, переданное компоненту или объекту. В Naive UI это особенно часто встречается при использовании пропсов компонентов. Например, компонент NButton ожидает определённый набор пропсов, и передача неподдерживаемого свойства вызовет:

const MyButton = () => <NButton color="primary" customProp="value" />

Ошибка:

Property 'customProp' does not exist on type 'ButtonProps'.

Решение:

  • Проверять документацию Naive UI и типы пропсов.
  • Использовать утверждение типов, если уверены в корректности данных:
<NButton color="primary" {...(myProps as Partial<ButtonProps>)} />
  • Создавать обёртку компонента с расширением типов через extends.

Ошибки с ref и реактивными объектами

В Naive UI многие компоненты используют реактивные свойства Vue. Проблемы возникают при попытке передать значение ref напрямую, не учитывая тип:

const value = ref<string>('')
<NInput v-model:value={value} />

Ошибка Type 'Ref<string>' is not assignable to type 'string' может появиться при неправильной привязке через JSX/TSX.

Правильное использование:

  • В Vue 3 с JSX/TSX для Naive UI рекомендуется использовать .value при передаче или правильно типизировать v-model:
<NInput v-model:value={value.value} />
  • Альтернатива — использовать тип Ref<string> с поддержкой v-model через DefineComponent.

Ошибки типа Type 'undefined' is not assignable to type '...'

Многие компоненты Naive UI имеют обязательные пропсы. Если не задать их, TypeScript сообщит:

<NDatePicker v-model:value={selectedDate} />

Ошибка:

Type 'undefined' is not assignable to type 'Dayjs'.

Причины:

  • Неинициализированный ref.
  • Некорректное использование реактивного объекта.

Решение:

  • Инициализировать реактивные значения с корректным типом:
const selectedDate = ref<Dayjs>(dayjs())
  • Использовать опциональные пропсы через ? и проверять наличие значения перед передачей.

Ошибки с обработчиками событий

Naive UI поддерживает типизированные события, например onUpdate:value для v-model. При передаче функции с некорректной сигнатурой TypeScript выдаст ошибку:

<NInput onUpdate:value={(val: number) => console.log(val)} />

Ошибка:

Type '(val: number) => void' is not assignable to type '(value: string) => void'.

Решение:

  • Использовать точные типы пропсов события:
<NInput onUpdate:value={(val: string) => console.log(val)} />
  • Если тип неизвестен, использовать универсальный unknown и кастинг после проверки:
<NInput onUpdate:value={(val: unknown) => console.log(val as string)} />

Проблемы с типами слотов

Naive UI активно использует слоты. При использовании JSX/TSX или <template> с TypeScript могут возникнуть ошибки:

<NCard v-slots={{ header: <div>{headerText}</div> }} />

Ошибка:

Type '{ header: Element; }' is not assignable to type 'Slots'.

Решение:

  • Явно указать тип слота:
<NCard v-slots={{ header: () => <div>{headerText}</div> }} />
  • В JSX использовать функцию для слота вместо прямого элемента.

Ошибки с комбинированными типами и кастомными объектами

Naive UI предоставляет множество сложных интерфейсов, например для NDataTable:

const columns: TableColumn[] = [
  { title: 'Name', key: 'name' },
  { title: 'Age', key: 'age', sorter: true },
]

Ошибка часто возникает при несоответствии типов ключей или сортировки:

Type '{ title: string; key: string; sorter: boolean; }' is not assignable to type 'TableColumn'.

Решение:

  • Использовать точные типы, предоставленные Naive UI: TableColumn<DataType>
  • Типизировать данные таблицы, чтобы соответствовать ключам столбцов:
interface DataType {
  name: string
  age: number
}
const columns: TableColumn<DataType>[] = [
  { title: 'Name', key: 'name' },
  { title: 'Age', key: 'age', sorter: (a, b) => a.age - b.age },
]

Советы по минимизации TypeScript ошибок

  • Использовать официальные типы Naive UI вместо any.
  • При работе с реактивными объектами и ref всегда учитывать .value.
  • Проверять сигнатуры событий и слотов перед использованием.
  • Расширять типы через extends для кастомных компонентов.
  • Инициализировать все обязательные пропсы и реактивные переменные корректными значениями.

Эти подходы позволяют максимально использовать преимущества строгой типизации TypeScript, предотвращая ошибки и упрощая масштабирование приложений с Naive UI.