Конфигурация TypeScript с Vue

TypeScript обеспечивает строгую типизацию и расширенные возможности для разработки масштабируемых приложений на Vue.js. Интеграция TypeScript в Vue требует понимания структуры проекта, конфигурации сборщика и особенностей синтаксиса Vue с типами.


Инициализация проекта с TypeScript

Для создания нового проекта с поддержкой TypeScript используется Vue CLI:

vue create my-vue-ts-app

При выборе настроек необходимо включить опцию TypeScript. CLI автоматически добавит базовые конфигурации, включая:

  • tsconfig.json — настройки компилятора TypeScript;
  • .vue файлы с поддержкой <script lang="ts">;
  • Типы для Vue, Vue Router и Vuex (если выбран).

Конфигурация tsconfig.json

Файл tsconfig.json управляет компиляцией TypeScript и должен быть настроен под особенности Vue. Пример минимальной конфигурации:

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
    "types": ["vite/client"]
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"],
  "exclude": ["node_modules"]
}

Ключевые параметры:

  • strict: включает строгий режим проверки типов.
  • jsx: "preserve": необходимо для поддержки JSX в Vue.
  • baseUrl и paths: позволяют использовать алиасы при импортах.
  • types: указывает на глобальные типы, включая клиентские определения для Vite.

Настройка Vue с TypeScript

В .vue файлах необходимо использовать <script lang="ts"> для поддержки типизации. Пример компонента:

<template>
  <div>{{ message }}</div>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';

export default defineComponent({
  name: 'HelloWorld',
  setup() {
    const message = ref<string>('Привет, Vue с TypeScript!');
    return { message };
  }
});
</script>

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

  • ref<string> указывает тип реактивной переменной.
  • defineComponent обеспечивает корректную работу с типами props и emits.

Типизация props, emits и slots

Props:

props: {
  title: {
    type: String,
    required: true
  },
  count: Number
}

Можно использовать интерфейсы для более строгой типизации:

interface Props {
  title: string;
  count?: number;
}

export default defineComponent({
  props: {} as Props,
  setup(props: Props) {
    console.log(props.title);
  }
});

Emits:

export default defineComponent({
  emits: ['submit'],
  setup(_, { emit }) {
    const submitForm = () => {
      emit('submit', { success: true });
    };
    return { submitForm };
  }
});

Slots:

export default defineComponent({
  setup(_, { slots }) {
    return () => (
      <div>
        {slots.default ? slots.default() : 'Слот по умолчанию'}
      </div>
    );
  }
});

Подключение Vue Router и Vuex с TypeScript

Vue Router:

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import Home from '@/views/Home.vue';

const routes: Array<RouteRecordRaw> = [
  { path: '/', component: Home }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

export default router;

Vuex (Pinia):

import { defineStore } from 'pinia';

export const useMainStore = defineStore('main', {
  state: () => ({
    counter: 0
  }),
  actions: {
    increment() {
      this.counter++;
    }
  }
});

Типизация состояния и действий обеспечивает автодополнение и проверку типов при разработке.


Интеграция с Vite

Для проектов на Vite рекомендуется использовать плагин @vitejs/plugin-vue и поддержку TypeScript по умолчанию:

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': '/src'
    }
  }
});

Советы по эффективной типизации

  1. Использовать defineComponent и ref с указанием типов для всех реактивных данных.
  2. Создавать интерфейсы для props, state и emits для лучшей читаемости и автодополнения.
  3. Избегать any, если возможно, заменяя на конкретные типы.
  4. Использовать глобальные типы для компонентов, если проект большой.
  5. Разделять типы и логику в отдельные файлы .d.ts или types.ts для поддерживаемости.

Проблемы и их решения

  • Ошибка с типами .vue: убедиться, что shims-vue.d.ts присутствует и содержит:
declare module '*.vue' {
  import { DefineComponent } from 'vue';
  const component: DefineComponent<{}, {}, any>;
  export default component;
}
  • Конфликты типов при Vue Router: убедиться, что типы маршрутов объявлены корректно через RouteRecordRaw.

  • Ошибка при импортах: проверить paths и baseUrl в tsconfig.json.


Эта конфигурация обеспечивает максимально безопасное и производительное использование TypeScript в проектах Vue.js, позволяя создавать масштабируемые приложения с полной поддержкой типизации, автодополнения и строгой проверки кода.