TypeScript поддержка из коробки

Vue.js начиная с версии 3 предлагает полноценную поддержку TypeScript, позволяя создавать масштабируемые и типобезопасные приложения. В основе лежит архитектура Composition API, которая тесно интегрируется с возможностями TypeScript, обеспечивая строгую проверку типов и автодополнение.


Настройка проекта с TypeScript

Для создания нового проекта с TypeScript используется официальный CLI @vue/cli или Vite. Пример инициализации через Vite:

npm create vite@latest my-vue-app -- --template vue-ts
cd my-vue-app
npm install
npm run dev

Структура проекта сразу включает файлы с расширением .ts и .vue, где можно использовать <script lang="ts">.

Пример базового компонента:

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

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

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

Ключевой момент: использование ref<string> и строгая типизация данных, возвращаемых из setup.


Типизация Props

Props в Vue 3 с TypeScript описываются с помощью интерфейсов или типов:

interface UserProps {
  name: string;
  age?: number;
}

export default defineComponent({
  props: {
    user: {
      type: Object as () => UserProps,
      required: true
    }
  },
  setup(props) {
    console.log(props.user.name);
  }
});

Также возможно использование PropType из Vue для более точного контроля:

import { PropType } from 'vue';

props: {
  user: {
    type: Object as PropType<UserProps>,
    required: true
  }
}

PropType обеспечивает строгую проверку типов на этапе компиляции и предотвращает ошибки при передаче неправильных данных.


Типизация реактивных данных

Vue 3 предлагает два основных метода создания реактивных данных: ref и reactive.

Ref создаёт реактивное примитивное значение:

const count = ref<number>(0);
count.value++;

Reactive создаёт реактивный объект:

const state = reactive<{ name: string; age: number }>({
  name: 'Иван',
  age: 25
});

state.age++;

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


Типизация методов и computed

Методы и вычисляемые свойства также можно типизировать:

import { computed } from 'vue';

const numbers = ref<number[]>([1, 2, 3]);

const sum = computed<number>(() => numbers.value.reduce((a, b) => a + b, 0));

function multiply(a: number, b: number): number {
  return a * b;
}

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


Компоненты с Composition API и TypeScript

Использование Composition API позволяет полностью раскрыть преимущества TypeScript:

interface Todo {
  id: number;
  title: string;
  completed: boolean;
}

export default defineComponent({
  setup() {
    const todos = ref<Todo[]>([]);
    
    function addTodo(title: string) {
      todos.value.push({ id: Date.now(), title, completed: false });
    }

    return { todos, addTodo };
  }
});

Преимущество в том, что все свойства todos и методы addTodo строго типизированы, а IDE предоставляет автодополнение и подсказки.


TypeScript и Vuex / Pinia

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

Пример с Pinia:

import { defineStore } from 'pinia';

interface State {
  count: number;
}

export const useCounterStore = defineStore('counter', {
  state: (): State => ({ count: 0 }),
  actions: {
    increment(amount: number) {
      this.count += amount;
    }
  }
});

Все мутации и доступ к состоянию строго проверяются TypeScript, что исключает ошибки при передаче неправильных типов данных.


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

TypeScript позволяет точно описывать события компонента:

export default defineComponent({
  emits: {
    'update': (value: number) => typeof value === 'number'
  },
  setup(_, { emit }) {
    emit('update', 42); // валидно
    // emit('update', 'text'); // ошибка компиляции
  }
});

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


Выводы по интеграции

TypeScript в Vue.js обеспечивает:

  • Строгую проверку типов данных на этапе компиляции.
  • Улучшенное автодополнение и документацию в IDE.
  • Возможность строить крупные масштабируемые приложения без скрытых ошибок.
  • Легкую интеграцию с современными инструментами, такими как Pinia, Vue Router и Composition API.

Использование TypeScript вместе с Vue 3 создаёт мощный инструмент для построения безопасных и предсказуемых интерфейсов.