How To Use Vue 3 TypeScript

A comprehensive guide to building type-safe Vue 3 applications with first-class TypeScript integration, from project setup to enterprise patterns.

Why Use TypeScript with Vue 3

TypeScript has become the industry standard for building maintainable JavaScript applications. Vue 3 was rewritten in TypeScript itself, meaning all official Vue packages include type declarations that work out of the box. This native integration means you get type checking, intelligent autocompletion, and refactoring support throughout your entire application.

The benefits extend beyond developer experience. A type system like TypeScript can detect many common errors via static analysis at build time, reducing the chance of runtime errors in production. For large-scale applications, this translates to fewer bugs reaching users and more confidence when refactoring codebases.

Vue 3's Composition API works particularly well with TypeScript. The setup function and script setup syntax provide clean patterns for defining component types, props, and emits. Unlike Vue 2, which required manual type annotations throughout, Vue 3 leverages TypeScript's inference capabilities to understand component structure automatically.

Real-world impact: When working on a complex dashboard application with 50+ components, TypeScript's type checking caught a prop type mismatch during development that would have caused a runtime error in production. The component API became self-documenting--new team members could see exactly what data each component expected without reading implementation details.

Key Benefits of Vue 3 + TypeScript

Static Error Detection

Catch type mismatches and common mistakes at build time rather than runtime

Improved IDE Support

Get accurate auto-completion, inline documentation, and refactoring tools

Better Code Documentation

Types serve as implicit documentation for component APIs

Safer Refactoring

Type checking makes large-scale code changes more reliable

Setting Up Your Vue 3 TypeScript Project

The official project scaffolding tool, create-vue, offers the cleanest path to a TypeScript-ready Vue project. This tool creates a Vite-powered application with pre-configured TypeScript support. For teams building modern web applications, having a properly configured development environment from the start is essential for long-term maintainability.

Run the scaffolding tool and enable TypeScript when prompted--it's the first option and the foundation for everything else. You can also add Vue Router, Pinia for state management, and testing tools at this stage. The project structure includes several TypeScript-specific files: the tsconfig.json file controls TypeScript compilation, and the src directory contains .vue files with lang="ts" attributes.

The scaffolded project uses Vite as the build tool, which handles TypeScript transpilation during development. Vite uses esbuild for fast transpilation without performing full type checking--this keeps the development server responsive while still catching basic syntax errors. For comprehensive type checking before production builds, the scaffold includes vue-tsc, a wrapper around tsc that supports Vue SFCs.

After project creation, install dependencies and verify your TypeScript setup by checking that the development server starts without TypeScript-related warnings. The create-vue tool pre-configures path aliases like @/ for src imports, ensuring consistent imports across your codebase. This foundation enables your team to focus on building features rather than configuring tooling.

Creating a Vue 3 TypeScript Project
1# Create a new Vue 3 project with TypeScript2npm create vue@latest3 4# Select TypeScript when prompted5# Install dependencies6cd your-project-name7npm install

TypeScript Configuration Essentials

The tsconfig.json file controls how TypeScript compiles your code. Projects scaffolded via create-vue include the @vue/tsconfig package, which provides base configurations optimized for Vue development.

Essential compiler options for Vue projects:

  • strict: true - Enables all strict type checking options, catching more potential issues at build time
  • isolatedModules: true - Required for Vite's esbuild transpilation to work correctly
  • moduleResolution: "bundler" - Modern resolution strategy designed for Vite and other bundlers
  • paths - Configures path aliases like @/ for src imports, ensuring TypeScript understands these during type checking
  • noEmit: true - Prevents TypeScript from outputting JavaScript files since Vite handles this

Project references ensure correct types for code running in different environments. For example, app code and test code might have different global variables. The references array in tsconfig.json manages these environments, keeping type checking fast while maintaining accuracy across your entire project.

The @vue/tsconfig package handles many configuration details automatically through TypeScript's Project References feature, ensuring correct types for each context without manual tuning. When scaling your application, these configurations become critical for maintaining type safety across larger codebases.

Essential tsconfig.json Settings for Vue
1{2 "compilerOptions": {3 "target": "ESNext",4 "module": "ESNext",5 "moduleResolution": "bundler",6 "strict": true,7 "jsx": "preserve",8 "resolveJsonModule": true,9 "isolatedModules": true,10 "esModuleInterop": true,11 "lib": ["ESNext", "DOM"],12 "skipLibCheck": true,13 "noEmit": true,14 "paths": {15 "@/*": ["./src/*"]16 }17 },18 "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]19}

Type-Safe Component Props and Emits

In Vue 3 with <script setup>, you can define props using TypeScript generics. The defineProps macro accepts a generic type parameter that defines the props structure, providing both runtime validation and compile-time type checking.

For default values, use the withDefaults helper. This approach provides both TypeScript types and runtime defaults without duplicating type information. Define emits with defineEmits using type-safe event signatures that ensure consumers pass correct payloads while providing autocomplete for event names and parameters.

Vue 3.3+ also supports a more concise tuple syntax for emit types: update: [value: string] instead of the function signature style. This reduces boilerplate while maintaining full type safety.

The template also receives type checking when lang="ts" is present. If you attempt to call a method that doesn't exist or use a variable incorrectly in template expressions, the type system catches the error during development. For teams working on web development projects, this level of type safety significantly reduces runtime errors and improves code quality.

Type-Safe Props and Emits
1<script setup lang="ts">2interface Props {3 title: string4 count?: number5 items: string[]6}7 8// Type-safe props with inference9const props = defineProps<Props>()10 11// Default values with withDefaults12const propsWithDefaults = withDefaults(defineProps<Props>(), {13 count: 0,14 items: () => []15})16 17// Type-safe emits18const emit = defineEmits<{19 (e: 'update', value: string): void20 (e: 'delete', id: number): void21}>()22</script>

Pinia State Management with TypeScript

Pinia, Vue's recommended state management library, was designed with TypeScript from the ground up. Using Pinia with TypeScript provides type-safe access to state, getters, and actions throughout your application.

The setup store syntax works particularly well with TypeScript. You define state with ref(), computed properties with computed(), and actions as plain functions--all fully type-safe. State variables infer their types from initial values or explicit annotations, while getters automatically infer return types.

When using Pinia stores in components, remember that destructuring loses reactivity. Use storeToRefs for reactive state properties to maintain reactivity while destructuring. Actions can be destructured directly since they're plain functions that don't rely on Vue's reactivity system.

This pattern ensures type-safe API calls, correctly typed state access, and reliable action invocation with full parameter checking. The TypeScript interface defines your data shape, making the store contract explicit and self-documenting. For enterprise applications requiring robust state management, combining Pinia with TypeScript creates a maintainable foundation that scales effectively.

Type-Safe Pinia Store
1import { defineStore } from 'pinia'2import { ref, computed } from 'vue'3 4interface UserInfo {5 id: number6 name: string7 email: string8}9 10export const useUserStore = defineStore('user', () => {11 // State with type annotations12 const token = ref<string>('')13 const userInfo = ref<UserInfo | null>(null)14 15 // Computed properties with inference16 const isLoggedIn = computed(() => !!token.value)17 const userName = computed(() => userInfo.value?.name ?? 'Guest')18 19 // Actions are fully typed20 async function login(email: string, password: string): Promise<void> {21 // Type-safe API calls22 const response = await fetch('/api/login', {23 method: 'POST',24 body: JSON.stringify({ email, password })25 })26 userInfo.value = await response.json()27 }28 29 return { token, userInfo, isLoggedIn, userName, login }30})

Vue Router Type Safety

Vue Router 4 provides TypeScript support through proper type annotations in route configuration. Add type safety to route metadata by extending Vue Router's RouteMeta interface.

This enables typed access to route meta properties throughout your application, including in navigation guards. Type-safe navigation guards ensure you're accessing the correct properties on route records with compile-time checking.

Combine this with Pinia stores to create authentication and authorization guards that are both type-safe and maintainable. TypeScript ensures you're accessing the correct properties on route records, preventing subtle bugs from typos or incorrect property access.

The pattern extends to route params and query strings as well, enabling fully typed navigation and route data access across your application. For single-page applications requiring SEO optimization, properly typed routing ensures consistent URL structures and proper metadata handling across all routes.

Type-Safe Vue Router Configuration
1import type { RouteRecordRaw } from 'vue-router'2 3// Extend RouteMeta for type-safe metadata4declare module 'vue-router' {5 interface RouteMeta {6 title?: string7 requiresAuth?: boolean8 roles?: string[]9 }10}11 12const routes: RouteRecordRaw[] = [13 {14 path: '/dashboard',15 name: 'Dashboard',16 component: () => import('@/views/dashboard/index.vue'),17 meta: {18 title: 'Dashboard',19 requiresAuth: true,20 roles: ['admin', 'editor']21 }22 }23]24 25// Type-safe navigation guard26router.beforeEach((to, from, next) => {27 if (to.meta.requiresAuth && !userStore.isLoggedIn) {28 next({ name: 'login', query: { redirect: to.fullPath } })29 return30 }31 if (to.meta.roles) {32 const hasRole = to.meta.roles.some(role => 33 userStore.userInfo?.roles?.includes(role)34 )35 if (!hasRole) next({ name: 'unauthorized' })36 else next()37 } else {38 next()39 }40})

Advanced TypeScript Patterns

Vue 3 supports generic components for reusable, type-safe components. Use the generic attribute on script setup to create components that work with multiple data types while maintaining full type safety.

When <script lang="ts"> is present, Vue SFCs also perform type checking in template expressions. This catches errors early and provides autocomplete within templates, extending TypeScript's benefits to the entire component including its markup.

Key advanced patterns include:

  • Generic components for list and data display components that work with multiple item types
  • Type utilities for extracting and transforming prop/emit types
  • Template type checking to catch template expression errors during development
  • Composable type patterns for shared logic with type safety

These patterns enable building highly reusable component libraries while maintaining the type safety that makes large codebases manageable. Teams implementing AI automation solutions often find these patterns valuable when building type-safe integrations with external APIs and services.

Generic Components in Vue 3
1<script setup lang="ts" generic="T extends { id: number }">2interface Props<T> {3 items: T[]4 selectedId?: number5}6 7const props = defineProps<Props<T>>()8 9const emit = defineEmits<{10 (e: 'select', item: T): void11 (e: 'delete', id: number): void12}>()13 14// Template also gets full type checking15function handleSelect(item: T) {16 emit('select', item)17}18</script>19 20<template>21 <div v-for="item in items" :key="item.id">22 <slot :item="item"></slot>23 </div>24</template>

Code Quality and Standards

Use ESLint 9 with TypeScript and Vue plugins for consistent code standards. Configure eslint-plugin-vue and @typescript-eslint to catch issues early and enforce your team's coding conventions.

For IDE support, Visual Studio Code with the Vue - Official extension provides TypeScript support inside Vue SFCs, type-aware auto-completion, and inline type tooltips. The extension replaces Vetur, the previous official extension, and provides superior TypeScript integration for Vue 3.

Recommended tooling setup:

  • Vue - Official VS Code extension for Vue SFC support
  • vue-tsc for command-line type checking in CI pipelines
  • ESLint 9 with @typescript-eslint and eslint-plugin-vue
  • Type-aware parser options in ESLint configuration

Run type checking before commits or in CI to catch type errors early. This prevents type-related issues from reaching production and ensures consistent code quality across your team. Our web development services include establishing these quality standards from project inception.

Frequently Asked Questions

Is TypeScript required for Vue 3?

No, TypeScript is optional but highly recommended. Vue 3 works great with plain JavaScript, but TypeScript provides significant benefits for maintainability and developer experience in larger projects.

Does TypeScript increase bundle size?

No, TypeScript types are stripped during compilation. They only affect development-time type checking and IDE support, not the production JavaScript bundle.

Can I mix TypeScript and JavaScript in one project?

Yes, Vue 3 projects can include both .ts and .js files. However, fully embracing TypeScript provides the most benefits for type safety.

What about Vue 2 projects?

Vue 2 has limited TypeScript support through vue-class-component and other libraries. For new projects, Vue 3 is strongly recommended for its first-class TypeScript integration.

Summary

Vue 3's first-class TypeScript support makes it an excellent choice for building type-safe applications. The key takeaways from this guide:

  1. Project Setup - Use create-vue with TypeScript template for optimal configuration with Vite and @vue/tsconfig
  2. Type Safety - Leverage defineProps and defineEmits with TypeScript generics for component API contracts
  3. State Management - Pinia provides excellent TypeScript integration using the Composition API style with full type inference
  4. Routing - Extend RouteMeta for type-safe navigation guards and route metadata access
  5. Code Quality - Use ESLint 9 with TypeScript and Vue plugins alongside vue-tsc for consistent code standards

By following these patterns, you can build maintainable, type-safe Vue 3 applications that scale well as your project grows. The investment in TypeScript pays dividends throughout a project's lifecycle--type errors caught at build time cost far less than bugs discovered in production.

Ready to build robust, type-safe Vue 3 applications? Our web development services team specializes in modern Vue applications with enterprise-grade type safety practices.

Build Type-Safe Vue 3 Applications

Need help implementing Vue 3 with TypeScript? Our team specializes in modern web development with robust type safety practices.

Sources

  1. Vue.js Official Documentation - TypeScript Overview - Comprehensive guide covering Vue TypeScript integration, project setup, and best practices
  2. Vue.js TypeScript Composition API Guide - Specific guidance for using TypeScript with Composition API and script setup
  3. Vue 3 + TypeScript Best Practices: 2025 Enterprise Architecture Guide - Enterprise patterns for Vue 3 + TypeScript + Pinia + Vue Router stack