LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 3916 min read

TypeScript with Vue

Add TypeScript to a Vue project and type props, emits, and refs correctly in the Composition API.

Why Vue and TypeScript Fit Well Together

Vue 3 was written in TypeScript from the ground up, giving strong, near-automatic type inference throughout the Composition API — refs, computed properties, and props all carry accurate types with minimal manual annotation.

Adding TypeScript to a Project

Selecting TypeScript during npm create vue@latest sets everything up automatically. To add it afterward, install the dependencies and rename .vue files' script blocks.

npm install --save-dev typescript vue-tsc
<script setup lang="ts">
// the lang="ts" attribute is what enables TypeScript in this block
</script>

Typing Props

defineProps accepts a TypeScript type or interface directly as a generic argument, an alternative to the runtime object syntax used earlier in this course.

<script setup lang="ts">
interface Props {
title: string;
price: number;
inStock?: boolean; // optional prop
}
const props = defineProps<Props>();
</script>

Default values for optional props use withDefaults alongside this syntax.

const props = withDefaults(defineProps<Props>(), {
inStock: true,
});

Typing Emits

<script setup lang="ts">
const emit = defineEmits<{
liked: [];
updateQuantity: [amount: number];
}>();
emit('updateQuantity', 1); // fully type-checked
</script>

Typing Refs and Computed

ref() infers its type from the initial value automatically; provide an explicit generic when the initial value doesn't fully describe the type (like starting from null).

import { ref, computed } from 'vue';
const count = ref(0); // inferred as Ref<number>
interface User { name: string; age: number; }
const user = ref<User | null>(null); // explicit generic needed here
const isAdult = computed(() => (user.value?.age ?? 0) >= 18); // inferred as ComputedRef<boolean>
vue-tsc for Full Template Checking

Regular tsc doesn't understand .vue files' templates — run vue-tsc instead (or alongside it) to catch type errors inside templates too, not just <script> blocks.

FAQs

Yes — it's per-file; without it, Vue treats the block as plain JavaScript even in a TypeScript project.

Yes — the official Vue - Official extension provides full type-checking and autocomplete inside templates when the project uses TypeScript.

Summary

TypeScript integrates deeply into Vue's Composition API, with defineProps<T>() and defineEmits<T>() giving fully type-checked component contracts. Next, you'll look at testing Vue components.

Next Lesson →

Testing Vue Components