Back to Blog

TypeScript Best Practices for Vue 3

0 min read Ali Arghyani
typescriptvuebest-practicescomposition-api

TypeScript Best Practices for Vue 3

TypeScript has become an essential tool for building robust Vue 3 applications. In this guide, we'll explore best practices for leveraging TypeScript's type system with Vue 3's Composition API.

Type-Safe Props

Define props with proper TypeScript interfaces:

<script setup lang="ts">
interface Props {
  title: string
  count?: number
  items: string[]
}

const props = defineProps<Props>()
</script>

Typed Composables

Create reusable composables with full type safety:

export function useCounter(initialValue = 0) {
  const count = ref<number>(initialValue)
  
  const increment = (): void => {
    count.value++
  }
  
  const decrement = (): void => {
    count.value--
  }
  
  return {
    count: readonly(count),
    increment,
    decrement
  }
}

Generic Components

Build flexible components with generics:

<script setup lang="ts" generic="T extends { id: string }">
interface Props {
  items: T[]
  onSelect: (item: T) => void
}

const props = defineProps<Props>()
</script>

Type-Safe Event Emits

Define emits with proper typing:

<script setup lang="ts">
interface Emits {
  (e: 'update', value: string): void
  (e: 'delete', id: number): void
}

const emit = defineEmits<Emits>()
</script>

Utility Types

Leverage TypeScript utility types:

// Pick specific properties
type UserPreview = Pick<User, 'id' | 'name' | 'email'>

// Make all properties optional
type PartialUser = Partial<User>

// Make all properties required
type RequiredUser = Required<User>

// Exclude properties
type UserWithoutPassword = Omit<User, 'password'>

Type Guards

Implement type guards for runtime type checking:

function isUser(value: unknown): value is User {
  return (
    typeof value === 'object' &&
    value !== null &&
    'id' in value &&
    'name' in value
  )
}

Async Data Typing

Type your async data properly:

const { data, pending, error } = await useAsyncData<User[]>(
  'users',
  () => $fetch('/api/users')
)

Conclusion

TypeScript enhances Vue 3 development by providing type safety, better IDE support, and improved code maintainability. By following these best practices, you'll build more robust and maintainable applications.

Remember: TypeScript is a tool to help you, not hinder you. Start simple and gradually add more type safety as needed.

Share this post
Ali Arghyani logo

© 2025, AliArghyani - All rights reserved.

GitHub