Использование TypeScript в проектах на Vue.js обеспечивает статическую типизацию, улучшает поддержку IDE и повышает надёжность кода. Vue 3 изначально оптимизирован под работу с TypeScript, что позволяет интегрировать его практически без потери производительности.
Для создания нового Vue проекта с TypeScript используется официальный инструмент Vue CLI или Vite. Основной подход:
# С Vue CLI
vue create my-vue-app
# В процессе выбора опций выбрать TypeScript
При использовании Vite:
npm create vite@latest my-vue-app
cd my-vue-app
npm install
# Выбрать шаблон 'vue-ts'
Оба инструмента автоматически создают конфигурацию TypeScript и
устанавливают необходимые зависимости, включая
tsconfig.json.
tsconfig.json)Файл tsconfig.json определяет поведение компилятора
TypeScript. Для Vue проекта рекомендуется следующая базовая
конфигурация:
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"skipLibCheck": true,
"types": ["vite/client"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"]
}
Ключевые моменты:
.ts, .vue и определений типов
.d.ts.Vue 3 использует Composition API, что делает интеграцию с TypeScript особенно удобной. Стандартный пример компонента с типизацией:
<script lang="ts" setup>
import { ref, computed } from 'vue';
const count = ref<number>(0);
const doubleCount = computed<number>(() => count.value * 2);
function increment(): void {
count.value++;
}
</script>
<template>
<div>
<p>Count: {{ count }}</p>
<p>Double: {{ doubleCount }}</p>
<button @click="increment">Increment</button>
</div>
</template>
Особенности:
lang="ts" указывает на использование TypeScript.ref<number> и
computed<number> строго задают ожидаемые
значения.increment объявлена с явным типом возвращаемого
значения void.Для компонентов с props и событиями рекомендуется явное определение типов:
<script lang="ts" setup>
import { defineProps, defineEmits } from 'vue';
interface Props {
title: string;
count?: number;
}
const props = defineProps<Props>();
const emit = defineEmits<{
(e: 'update', value: number): void
}>();
function updateValue(newValue: number) {
emit('update', newValue);
}
</script>
<template>
<h1>{{ props.title }}</h1>
<p>{{ props.count }}</p>
<button @click="updateValue(5)">Update</button>
</template>
Props описывает свойства компонента.defineEmits позволяет типизировать события, что
предотвращает случайные ошибки при эмите событий.Composition API предоставляет возможность создавать переиспользуемые функции с типами:
import { ref } from 'vue';
export function useCounter(initial: number = 0) {
const count = ref<number>(initial);
function increment(): void {
count.value++;
}
return { count, increment };
}
Преимущества:
useCounter в
любом компоненте с полной поддержкой автодополнения и проверки
типов.count будут обнаружены на
этапе компиляции.Для 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;
При работе с Pinia типизация хранилища делается следующим образом:
import { defineStore } from 'pinia';
import { ref } from 'vue';
export const useCounterStore = defineStore('counter', () => {
const count = ref<number>(0);
function increment() {
count.value++;
}
return { count, increment };
});
TypeScript позволяет безопасно получать доступ к состоянию и действиям, предотвращая ошибки в крупных проектах.
TypeScript в Vue проектах обеспечивает структурированность кода, безопасность типов и комфортную работу с IDE. Правильная настройка проекта, компонентов, маршрутов и хранилища позволяет создавать масштабируемые приложения с минимальными ошибками.