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>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.