Настройка TypeScript

Element Plus — современная библиотека компонентов для Vue 3, предоставляющая полный набор UI-элементов. Для полноценного использования всех возможностей библиотеки в TypeScript необходимо правильно настроить проект. В этом разделе рассматриваются ключевые шаги по интеграции Element Plus с TypeScript, включая конфигурацию, типизацию компонентов и работу с динамическими свойствами.


Установка и базовая конфигурация TypeScript

Для начала необходимо убедиться, что проект Vue 3 настроен с поддержкой TypeScript. Если проект создается с нуля, рекомендуется использовать Vite или Vue CLI:

# Создание проекта с Vue CLI и TypeScript
vue create my-project
# Выбираем опцию TypeScript

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

npm create vite@latest my-project -- --template vue-ts

После создания проекта необходимо установить Element Plus и его типы:

npm install element-plus
npm install -D @types/node

@types/node необходим для корректной работы Node-типов в TypeScript, особенно при настройке сборки.


Настройка tsconfig.json

Файл tsconfig.json является ключевым для корректной работы TypeScript с Vue 3 и Element Plus. Основные моменты:

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "Node",
    "strict": true,
    "jsx": "preserve",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
    "types": ["node", "element-plus/global"]
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"],
  "exclude": ["node_modules"]
}

Ключевые моменты настройки:

  • strict: true — включает строгую проверку типов, что важно для надежной интеграции с Element Plus.
  • skipLibCheck: true — ускоряет сборку, игнорируя проверку типов сторонних библиотек.
  • types — добавление "element-plus/global" позволяет использовать глобальные компоненты без дополнительных деклараций.

Типизация компонентов Element Plus

Element Plus предоставляет встроенные типы для всех своих компонентов, но иногда требуется дополнительная настройка для корректной работы с props и событиями.

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

import { ElButton } from 'element-plus'
import type { ButtonProps } from 'element-plus'

const buttonProps: ButtonProps = {
  type: 'primary',
  disabled: false
}

Особенности:

  • ButtonProps содержит все допустимые свойства компонента <el-button>.
  • TypeScript будет выдавать ошибки при попытке передать несуществующее свойство или неправильный тип.

Для кастомных событий рекомендуется использовать Generic-параметры:

import { defineComponent } from 'vue'
import { ElInput } from 'element-plus'

export default defineComponent({
  components: { ElInput },
  setup() {
    const handleInput = (value: string) => {
      console.log(value)
    }
    return { handleInput }
  }
})

В данном примере TypeScript строго проверяет тип аргумента события input.


Автодекларация глобальных компонентов

Чтобы не импортировать каждый компонент вручную, можно воспользоваться автодекларацией:

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')

Для корректной типизации глобальных компонентов создается файл деклараций element-plus.d.ts в src/types:

import 'element-plus'
declare module 'vue' {
  interface GlobalComponents {
    ElButton: typeof import('element-plus')['ElButton']
    ElInput: typeof import('element-plus')['ElInput']
    // Добавлять остальные компоненты по мере необходимости
  }
}

После этого можно использовать <el-button> и <el-input> в шаблоне без ошибок TypeScript.


Работа с динамическими свойствами и типами

Element Plus поддерживает динамические props, такие как size, type, disabled. Для их строгой типизации полезно использовать Literal Types:

type ButtonType = 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'text'

const btnType: ButtonType = 'primary'

Также можно комбинировать с Vue ref и computed для реактивных свойств:

import { ref, computed } from 'vue'
import type { ButtonProps } from 'element-plus'

const buttonState = ref<'primary' | 'success'>('primary')

const buttonProps = computed<ButtonProps>(() => ({
  type: buttonState.value,
  disabled: false
}))

TypeScript будет автоматически проверять правильность значений и обеспечивать безопасное использование динамических данных.


Интеграция с Vuex/Pinia

При работе с глобальными состояниями, например через Pinia, типизация компонентов Element Plus становится особенно важной:

import { defineStore } from 'pinia'

export const useButtonStore = defineStore('button', {
  state: () => ({
    type: 'primary' as 'primary' | 'success',
    disabled: false
  }),
  getters: {
    buttonProps: (state) => ({
      type: state.type,
      disabled: state.disabled
    })
  }
})

В компоненте можно напрямую использовать типизированные props:

import { useButtonStore } from '@/stores/button'

const store = useButtonStore()
<el-button v-bind="store.buttonProps">Кнопка</el-button>

TypeScript обеспечит корректность всех передаваемых значений, предотвращая ошибки на этапе компиляции.


Полезные рекомендации

  • Всегда включать строгий режим TypeScript (strict: true) для работы с Element Plus.
  • Создавать отдельные файлы деклараций для глобальных компонентов, чтобы избежать дублирования импортов.
  • Использовать встроенные типы компонентов (ButtonProps, InputProps и др.) для предотвращения ошибок.
  • Типизировать события через аргументы функции и Generic-параметры Vue, чтобы сохранить строгую проверку.
  • Для динамических данных применять ref, computed и Literal Types для максимальной безопасности типов.

Эти шаги обеспечивают полную интеграцию Element Plus с TypeScript, делая проект строгим, предсказуемым и безопасным с точки зрения типов.