Zum Inhalt springen

TypeScript mit Vue

TypeScript erweitert JavaScript um Typen. Du schreibst dazu, welche Form ein Wert hat, und ein Werkzeug prüft vor dem Start, ob der Code dazu passt. Der Kurs verwendet JavaScript, create-vue fragt aber beim Anlegen eines Projekts, ob du TypeScript willst. In einem Projekt mit TypeScript steht in jeder Single File Component <script setup lang="ts">.

Laut Projektauftrag bringt durchgehend TypeScript einen Bonuspunkt. Es lohnt sich, sobald dein Projekt mehr als eine Handvoll Komponenten hat oder Daten von einer API bekommt. Der Editor zeigt dir dann schon beim Tippen, wenn eine Prop fehlt, ein Event die falschen Daten mitgibt oder ein Feld der API anders heisst. Plane etwas mehr Zeit ein, denn die Typen beschreibst du einmal selbst. Vite übersetzt TypeScript nur und prüft keine Typen, das macht erst vue-tsc.

Das Beispiel unter optional/typescript/de ist ein vereinfachter Katalog in TypeScript, mit Karten, Suche und Favoriten wie in den Teilen 3 bis 5. Ein Interface beschreibt ein Ding so, wie die Kurs-API es liefert.

types.ts
// One thing of the catalog, as the course API delivers it
export interface Item {
id: number
name: string
category: string
deposit: number
availableFrom: string | null
}

Die Karte legt ihre Props und ihr Event mit Typen fest statt mit Objekten wie { type: Boolean }. favorite = false beim Zerlegen der Props gibt den Standardwert. defineEmits beschreibt das Event als Liste der Werte, die es mitgibt.

ItemCard.vue
<script setup lang="ts">
import type { Item } from '../types'
// The types describe the props and the events, vue-tsc checks every use of the component
const { item, favorite = false } = defineProps<{
item: Item
favorite?: boolean
}>()
const emit = defineEmits<{
toggleFavorite: [id: number]
}>()
</script>

In App.vue braucht ref einen Typ nur dort, wo er sich nicht aus dem Anfangswert ergibt. Ein leeres Array hätte sonst den Typ never[], und kein Wert dürfte hinein.

App.vue
<script setup lang="ts">
import { computed, ref } from 'vue'
import items from '../data/items.json'
import { search } from './catalog'
import ItemCard from './components/ItemCard.vue'
import type { Item } from './types'
const catalog: Item[] = items
const query = ref('')
// Without the type argument the empty array would be never[]
const favorites = ref<number[]>([])
const hits = computed(() => search(catalog, query.value))
function toggleFavorite(id: number) {
favorites.value = favorites.value.includes(id) ? favorites.value.filter((favorite) => favorite !== id) : [...favorites.value, id]
}
</script>

npm run type-check startet vue-tsc. Gibt das Template der Karte als favorite einen Text statt eines Wahrheitswerts mit, meldet vue-tsc den Fehler mit Zeile und Spalte.

src/App.vue(28,33): error TS2322: Type 'string' is not assignable to type 'boolean | undefined'.

npm run build prüft die Typen zuerst und baut erst danach. Achte auf die Version von TypeScript. TypeScript 7 ist eine neue Umsetzung in Go, mit der vue-tsc nicht läuft, und das Team von TypeScript rät Projekten mit Vue, vorerst bei Version 6 zu bleiben. Das Beispiel verwendet deshalb 6.0.3. Installierst du TypeScript ohne Angabe der Version, bekommst du Version 7, und vue-tsc bricht ab.

Texte und Abbildungen stehen unter CC BY-SA 4.0, der Code unter der MIT-Lizenz und die Daten des Kurses unter CC0 1.0. Die Schrift der Abbildungen ist Kalam unter der SIL Open Font License 1.1. Die Quellen liegen auf GitHub.