Tutorials Logic, IN info@tutorialslogic.com

Vue TypeScript Typed Props Composables

Typed Vue Contracts

TypeScript improves Vue components when types describe public props, events, template refs, and service results. In <script setup>, defineProps and defineEmits accept type declarations, while ref and computed usually infer their value types. Types reduce invalid states but do not validate data arriving from a network or browser storage.

Typed Component Contracts

Props define what a parent may pass. Emits define what a child may send back. These should be the first Vue contracts you type.

  • Use defineProps with interfaces for complex props.
  • Use defineEmits for event payloads.
  • Avoid any for component boundaries.

Refs and Async State

Template refs and API data often start empty. TypeScript forces you to represent loading, null, success, and error states clearly.

  • Type DOM refs as nullable.
  • Represent async state with unions.
  • Do not assume API data is present before loading finishes.

Typed Composables

A composable becomes easier to reuse when its parameters and return value are typed. Consumers can discover correct usage in the editor.

  • Export shared interfaces.
  • Type API DTOs separately from UI view models.

Runtime and Static Types

Use unions for constrained UI states, such as idle, loading, success, and failure, so a component cannot represent contradictory booleans. Type nullable template refs because the element is absent before mount and after unmount. Avoid broad any values that postpone the same uncertainty until runtime.

Props still need runtime validation when JavaScript consumers use the component, and API responses need parsing or schema validation at the boundary. Keep domain interfaces near the domain rather than duplicating almost-identical component-local shapes. Run vue-tsc in CI because the bundler can transpile without proving template type correctness.

Typed Props and Emits

Typed Props and Emits
interface UserCardProps {
  user: { id: number; name: string; role: "admin" | "editor" | "viewer" };
}
const props = defineProps<UserCardProps>();
const emit = defineEmits<{ select: [userId: number] }>();

Type a Template Reference After Mount

The element is null before mounting, so the type and access both represent that lifecycle boundary.

Type a Template Reference After Mount
<script setup lang="ts">
import { onMounted, ref } from 'vue'

const searchInput = ref<HTMLInputElement | null>(null)
onMounted(() => searchInput.value?.focus())
</script>

<template><input ref="searchInput" type="search"></template>
Output
The search input receives focus after the component mounts.
  • Do not hide the initial null state with an unsafe type assertion.
Before you move on

Vue TypeScript Typed Props Composables Mastery Check

4 checks
  • Type props, defaults, emits, slots, and exposed component APIs at their boundaries.
  • Handle template refs as nullable until mount and narrow DOM or component instance types before use.
  • Preserve generic and return types in composables so callers do not fall back to any.
  • Use typed injection keys and run vue-tsc so template errors are checked with source code errors.

Vue TypeScript Questions Learners Ask

No, but TypeScript helps as components and data contracts grow.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.