TypeScript з опційним API 
Ця сторінка передбачає, що ви вже ознайомились із Використання Vue з TypeScript.
TIP
Хоча Vue підтримує використання TypeScript з Опційним API, все ж рекомендується використовувати TypeScript з Композиційним API, оскільки він пропонує простіший, ефективніший та надійніший спосіб визначення типу.
Типізація властивостей компонента 
Визначення типу реквізитів з Опційним API, вимагає обгорнення компонента за допомогою defineComponent(). При цьому Vue може визначити типи реквізитів на основі параметрів props, враховуючи додаткові параметри, такі як required: true і default:
ts
import { defineComponent } from 'vue'
export default defineComponent({
  // визначення типу ввімкнено
  props: {
    name: String,
    id: [Number, String],
    msg: { type: String, required: true },
    metadata: null
  },
  mounted() {
    this.name // тип: string | undefined
    this.id // тип: number | string | undefined
    this.msg // тип: string
    this.metadata // тип: any
  }
})Однак параметри props під час виконання, підтримують лише використання конструктора функцій, в якості типу реквізиту - немає способу вказати складні типи, такі як об'єкти з вкладеними властивостями або сигнатури виклику функції.
Щоб анотувати складні типи реквізитів, ми можемо використовувати утиліту типу PropType:
ts
import { defineComponent } from 'vue'
import type { PropType } from 'vue'
interface Book {
  title: string
  author: string
  year: number
}
export default defineComponent({
  props: {
    book: {
      // надання більш конкретного типу для `Object`
      type: Object as PropType<Book>,
      required: true
    },
    // також можна анотувати функції
    callback: Function as PropType<(id: number) => void>
  },
  mounted() {
    this.book.title // string
    this.book.year // number
    // TS Помилка: аргумент типу "string" не можна
    // призначити параметру типу 'number'
    this.callback?.('123')
  }
})Застереження 
Якщо ваша версія TypeScript нижча за 4.7, ви повинні бути обережними, використовуючи функції для опцій реквізиту validator і default - обов'язково використовуйте стрілочні функції:
ts
import { defineComponent } from 'vue'
import type { PropType } from 'vue'
interface Book {
  title: string
  year?: number
}
export default defineComponent({
  props: {
    bookA: {
      type: Object as PropType<Book>,
      // Обов’язково використовуйте стрілочні функції, якщо ваша версія TypeScript нижча за 4.7
      default: () => ({
        title: 'Arrow Function Expression'
      }),
      validator: (book: Book) => !!book.title
    }
  }
})Це запобігає TypeScript від необхідності визначати тип this у цих функціях, що, на жаль, може призвести до помилки визначення типу. Це обмеження було в попередній версії, і тепер покращено в TypeScript 4.7.
Типізація випромінювань компонента 
Ми можемо оголосити очікуваний тип корисного навантаження для випромінювача події, використовуючи об’єкт синтаксису опції emits. Крім того, усі неоголошені випромінювачі подій викликатимуть типову помилку:
ts
import { defineComponent } from 'vue'
export default defineComponent({
  emits: {
    addBook(payload: { bookName: string }) {
      // виконати перевірку під час виконання
      return payload.bookName.length > 0
    }
  },
  methods: {
    onSubmit() {
      this.$emit('addBook', {
        bookName: 123 // Помилка типу!
      })
      this.$emit('non-declared-event') // Типова помилка!
    }
  }
})Типізація обчислюваних властивостей 
Обчислювана властивість визначає свій тип на основі свого значення при поверненні:
ts
import { defineComponent } from 'vue'
export default defineComponent({
  data() {
    return {
      message: 'Hello!'
    }
  },
  computed: {
    greeting() {
      return this.message + '!'
    }
  },
  mounted() {
    this.greeting // тип: string
  }
})У деяких випадках ви можете явно анотувати тип обчислюваної властивості, щоб переконатися, в правильності реалізації:
ts
import { defineComponent } from 'vue'
export default defineComponent({
  data() {
    return {
      message: 'Hello!'
    }
  },
  computed: {
    // явно анотувати тип повернення
    greeting(): string {
      return this.message + '!'
    },
    // анотування доступної для запису обчисленої властивості
    greetingUppercased: {
      get(): string {
        return this.greeting.toUpperCase()
      },
      set(newValue: string) {
        this.message = newValue.toUpperCase()
      }
    }
  }
})Явні анотації також можуть знадобитися в деяких граничних випадках, коли TypeScript не може визначити тип обчисленої властивості через циклічні визначення.
Типізація обробників подій 
При роботі з нативними подіями DOM може бути корисним правильно типізувати аргумент, який ми передаємо обробнику. Розгляньмо це на прикладі:
vue
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
  methods: {
    handleChange(event) {
      // `event` неявно має тип "any".
      console.log(event.target.value)
    }
  }
})
</script>
<template>
  <input type="text" @change="handleChange" />
</template>Без анотації типу аргумент event неявно матиме тип any. Це також призведе до помилки TS, якщо "strict": true або "noImplicitAny": true використовуються в tsconfig.json. Тому рекомендується явно анотувати аргументи обробників подій. Крім того, вам може знадобитися явно надати властивості для event:
ts
import { defineComponent } from 'vue'
export default defineComponent({
  methods: {
    handleChange(event: Event) {
      console.log((event.target as HTMLInputElement).value)
    }
  }
})Доповнення глобальних властивостей 
Деякі плагіни інсталюють глобально доступні властивості для всіх екземплярів компонента за допомогою app.config.globalProperties. Наприклад, ми можемо інсталювати this.$http для отримання даних, або this.$translate для інтернаціоналізації. Щоб це добре працювало з TypeScript, Vue надає інтерфейс ComponentCustomProperties, призначений для доповнення за допомогою доповнення модуля TypeScript:
ts
import axios from 'axios'
declare module 'vue' {
  interface ComponentCustomProperties {
    $http: typeof axios
    $translate: (key: string) => string
  }
}Також до вашої уваги:
Розміщення доповнень типу 
Ми можемо розмістити це доповнення типу у файлі .ts або у файлі *.d.ts для всього проєкту. У будь-якому випадку переконайтеся, що його включено в tsconfig.json. Для авторів бібліотек/плагінів цей файл слід вказати у властивості types у package.json.
Щоб скористатися перевагами доповнення модуля, вам потрібно буде переконатися, що доповнення розміщено в модулі TypeScript. Тобто файл має містити принаймні один import або export верхнього рівня, навіть якщо це просто export {}. Якщо доповнення розміщено за межами модуля, воно перезапише вихідні типи, а не доповнить їх!
ts
// Не працює, перезаписує вихідні типи.
declare module 'vue' {
  interface ComponentCustomProperties {
    $translate: (key: string) => string
  }
}ts
// Працює правильно
export {}
declare module 'vue' {
  interface ComponentCustomProperties {
    $translate: (key: string) => string
  }
}Доповнення користувацьких параметрів 
Деякі плагіни, наприклад vue-router, забезпечують підтримку користувацьких параметрів компонента, таких як beforeRouteEnter:
ts
import { defineComponent } from 'vue'
export default defineComponent({
  beforeRouteEnter(to, from, next) {
    // ...
  }
})Без належного доповнення типу, аргументи цього хука неявно матимуть тип any. Ми можемо доповнити інтерфейс ComponentCustomOptions, щоб підтримувати ці користувацькі параметри:
ts
import { Route } from 'vue-router'
declare module 'vue' {
  interface ComponentCustomOptions {
    beforeRouteEnter?(to: Route, from: Route, next: () => void): void
  }
}Тепер параметр beforeRouteEnter буде правильного типу. Зауважте, що це лише приклад - добре типізовані бібліотеки, такі як vue-router, повинні автоматично виконувати ці доповнення у власних визначеннях типів.
Розміщення цього доповнення підпадає під ті самі обмеження, що й глобальні доповнення властивостей.
Також до вашої уваги: