https://vuejs.org/guide/typescript/composition-api.html#typing-reactive

ref

  1. import { ref } from 'vue'
  2. // inferred type: Ref<number>
  3. const year = ref(2020)
  4. // => TS Error: Type 'string' is not assignable to type 'number'.
  5. year.value = '2020'

reactive

  1. import { reactive } from 'vue'
  2. interface Book {
  3. title: string
  4. year?: number
  5. }
  6. const book: Book = reactive({ title: 'Vue 3 Guide' })

computed

  1. import { ref, computed } from 'vue'
  2. const count = ref(0)
  3. // inferred type: ComputedRef<number>
  4. const double = computed(() => count.value * 2)
  5. // => TS Error: Property 'split' does not exist on type 'number'
  6. const result = double.value.split('')

refs

  1. <script setup lang="ts">
  2. import { ref, onMounted } from 'vue'
  3. const el = ref<HTMLInputElement | null>(null)
  4. onMounted(() => {
  5. el.value?.focus()
  6. })
  7. </script>
  8. <template>
  9. <input ref="el" />
  10. </template>

props

  1. <script setup lang="ts">
  2. interface Props {
  3. foo: string
  4. bar?: number
  5. }
  6. // reactive destructure for defineProps()
  7. // default value is compiled to equivalent runtime option
  8. const { foo, bar = 100 } = defineProps<Props>()
  9. </script>
  1. <script setup lang="ts">
  2. const props = defineProps({
  3. foo: { type: String, required: true },
  4. bar: Number
  5. })
  6. props.foo // string
  7. props.bar // number | undefined
  8. </script>

emit

  1. <script setup lang="ts">
  2. // runtime
  3. const emit = defineEmits(['change', 'update'])
  4. // type-based
  5. const emit = defineEmits<{
  6. (e: 'change', id: number): void
  7. (e: 'update', value: string): void
  8. }>()
  9. </script>