# TypeScript With Vue — Vue.js

Source: https://www.skillbyai.com/en/vue/d-ts

> Typed props, emits and refs.

## Type-based declarations

With `<script setup lang="ts">`, `defineProps<{ ... }>()` declares props from a TypeScript type, and `withDefaults(defineProps<Props>(), { ... })` supplies defaults; Vue 3.5+ also allows defaults through reactive props destructuring. `defineEmits<{ change: [id: number] }>()` types event payloads (the tuple syntax needs Vue 3.3+). `ref<User | null>(null)` sets a ref's type when it cannot be inferred, template refs are typed with the element type, and `computed` infers its type from the getter. Use `InjectionKey<T>` for typed provide/inject. Because the TypeScript compiler cannot read `.vue` files, run `vue-tsc --noEmit` in CI for type checking. Check the docs for your version for the newest macros.

## A typed component

Props, defaults, emits and refs.

```vue
<script setup lang="ts">
import { ref, computed } from 'vue'

interface User { id: number; name: string; email: string }

const props = withDefaults(defineProps<{
  users: User[]
  pageSize?: number
}>(), { pageSize: 10 })

const emit = defineEmits<{
  select: [user: User]
  pageChange: [page: number]
}>()

const page = ref(1)
const selected = ref<User | null>(null)
const searchInput = ref<HTMLInputElement | null>(null)

const visible = computed(() =>
  props.users.slice((page.value - 1) * props.pageSize, page.value * props.pageSize))

function choose(user: User) {
  selected.value = user
  emit('select', user)        // emit('select', 42) would be a type error
}
</script>

<template>
  <input ref="searchInput" />
  <button v-for="u in visible" :key="u.id" @click="choose(u)">{{ u.name }}</button>
</template>
```

## Type-check in CI

`vite build` strips types without checking them. Add `vue-tsc --noEmit` to your build or CI script so type errors fail the pipeline.

**Quiz:** Which tool type-checks .vue files from the command line?

- [ ] tsc alone, with no plugins
- [x] vue-tsc
- [ ] vite build
- [ ] eslint --fix

*Answer:* vue-tsc. vue-tsc wraps TypeScript with Vue file support.
