TypeScript Generics in Vue 3: Flexibler Code ohne Typverlust
TL;DR: TypeScript Generics sind der elegante Mittelweg zwischen any-Chaos und copy-paste-Duplikaten. Jakub Andrzejewski vom Nuxt Ecosystem Team zeigt in einem aktuellen Praxis-Guide, wie Generic-Typen, ApiResponse<T>-Wrapper und keyof-Constraints Vue-Projekte typsicher und skalierbar machen.
Wer mit TypeScript in Vue-Projekten arbeitet, kennt das Dilemma: entweder man schreibt denselben Typ fünfmal mit leicht veränderten Datentypen, oder man greift zur any-Keule und verliert dabei Autocomplete, Typ-Inferenz und die Sicherheit, dass der Code zur Laufzeit tut, was man erwartet. TypeScript Generics lösen genau dieses Problem — und sie fügen sich besonders elegant in die Composition API von Vue 3 ein.
Die wichtigsten Punkte
- 📅 Veröffentlicht: 30. März 2026 auf DEV Community
- 🎯 Zielgruppe: Vue 3 Entwickler:innen mit TypeScript-Grundkenntnissen
- 💡 Kernfeature: Generische Typen als wiederverwendbare Typ-Platzhalter ohne Verlust von Type Safety
- 🔧 Tech-Stack: TypeScript, Vue 3 Composition API, Nuxt, VueUse
Was bedeutet das für Vue-Entwickler:innen?
Die Composition API von Vue 3 war der entscheidende Schritt hin zu erstklassiger TypeScript-Integration. Generics bringen diesen Ansatz auf die nächste Stufe: Statt für jede API-Route einen eigenen Response-Typen zu definieren, schreibt man einmal ApiResponse<T> — und das gesamte Projekt profitiert davon.
Besonders in Nuxt-Projekten mit vielen useFetch-Calls zahlt sich das aus. Anstatt bei jedem Datenabruf den Typ manuell zu casten, lässt sich ein typsicherer Composable definieren, der den Response-Typ als Generic-Parameter entgegennimmt.
Das Grundprinzip: Typ-Platzhalter statt any
Das Problem beginnt harmlos. Eine Funktion soll für verschiedene Typen funktionieren. Die schnelle Lösung:
function identity(value: any): any {
return value
}
Das funktioniert — aber man verliert Typ-Inferenz, Autocomplete und mögliche Compiler-Fehler, die echte Bugs verhindern könnten. Die Alternative ohne Generics führt zu Code-Duplikaten, die den DRY-Prinzipien widersprechen:
function identityString(value: string): string { return value }
function identityNumber(value: number): number { return value }
Mit Generics wird daraus eine einzige, typsichere Funktion:
function identity<T>(value: T): T {
return value
}
T ist ein Typ-Platzhalter, der beim Aufruf automatisch durch den konkreten Typ ersetzt wird. TypeScript inferiert den Rückgabetyp direkt aus dem Argument.
Praktische Anwendungen in Vue & Nuxt
Pattern 1: Wiederverwendbarer ApiResponse-Typ
Das häufigste und wertvollste Einsatzgebiet in Vue-Projekten ist ein generischer Wrapper für API-Antworten:
type ApiResponse<T> = {
data: T
error: string | null
}
In einem Nuxt-Projekt definiert man diesen Typ einmal in types/api.ts und nutzt ihn project-weit:
type User = { id: number; name: string }
const response: ApiResponse<User> = {
data: { id: 1, name: "Jakub" },
error: null
}
Kombiniert mit useFetch in Nuxt ergibt sich ein typsicheres Datenabruf-Muster:
const { data, error } = await useFetch<ApiResponse<User[]>>('/api/users')
// data.value?.data ist automatisch User[] — kein Type-Cast nötig
Pattern 2: keyof-Constraints für typsichere Zugriffe
Gerade in Form-Composables oder dynamischen Tabellenkomponenten ist folgender Pattern Gold wert:
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key]
}
const user = { id: 1, name: "Jakub" }
getProperty(user, "name") // ✅ TypeScript kennt den Rückgabetyp: string
getProperty(user, "age") // ❌ Compiler-Fehler — "age" existiert nicht auf User
Für Vue-Entwickler:innen besonders relevant: Dieser Ansatz lässt sich direkt in Composables für reaktive Formularfelder übersetzen.
Pattern 3: Generic Props in Vue-Komponenten
Vue 3.3+ (seit Mai 2023) erlaubt generische Komponenten direkt über das generic Attribut auf <script setup>. Das ermöglicht vollständig typisierte Listenkomponenten ohne Code-Duplikation:
<!-- Generische Listenkomponente -->
<script setup lang="ts" generic="T">
defineProps<{
items: T[]
}>()
</script>
Wichtig: Das generic="T" Attribut auf dem <script setup lang="ts"> Tag ist zwingend erforderlich — erst dadurch wird T als Typ-Parameter verfügbar. Die Komponente wird dann typsicher auf den Datentyp spezialisiert, sobald man sie mit konkreten Daten verwendet — die IDE kennt dann alle Properties der List-Items.
Developer Experience verbessert sich durch…
Die Verbesserungen sind spürbar im Alltag:
Autocomplete überall: Statt any-Typen, die die IDE zum Schweigen bringen, erhält man bei jedem Zugriff auf Generic-Daten vollständige Typ-Vorschläge.
Refactoring-Sicherheit: Ändert sich die Struktur eines API-Response-Typs, zeigt TypeScript sofort alle Stellen im Code, die angepasst werden müssen — quer durch alle Composables und Komponenten, die ApiResponse<T> nutzen.
Kein Cast-Overhead: Mit gut definierten Generics entfällt das manuelle as User[] an jeder Stelle. Der Typ fließt automatisch durch den Code.
Elegante Composables: Ein typsicheres useFetch<T> oder useLocalStorage<T> aus VueUse ist das direkte Ergebnis dieser Technik.
Praktische Nächste Schritte
- Startet mit
ApiResponse<T>: Legt in eurem nächsten Nuxt- oder Vue-Projekt einetypes/api.tsan und definiert dort einen generischen Response-Wrapper. Das zahlt sich sofort aus. - Refactored bestehende Composables: Schaut euch eure Custom Composables an — überall wo
anysteht oder mehrere fast-identische Funktionen existieren, sind Generics die richtige Antwort. - Jakubs weiterführenden Artikel lesen: Er hat einen separaten Deep-Dive zu generischen Props in Vue-Komponenten veröffentlicht, der die
<script setup generic>Syntax ausführlich behandelt. keyof-Pattern für Formulare anwenden: Wer dynamische Formular-Composables baut, sollteK extends keyof Tals Standard-Werkzeug in sein Repertoire aufnehmen.
Robin Böhm
Gründer von vuejs.de
Entwickler, Trainer und Buch-Autor
Robin beschäftigt sich seit 2012 intensiv mit der Erstellung client-seitiger Web-Applikationen. Mit seinem Schulungs-Unternehmen workshops.de bildet er Teams mit dem Fokus auf Web-Technologien aus.
Weitere Artikel
Vue State Management: Composables, Provide/Inject und Pinia – Die richtige Wahl für jede Situation
Vue State Management: Composables, Provide/Inject und Pinia – Die richtige Wahl für jede Situation
Der erste enterJS Vue Day 2021
Der enterJS Vue Day 2021 findet am 15. April zum ersten Mal statt. Einen Tag lang tauscht sich die Community über spannende Themen rund um VueJS aus.
JavaScript lernen und Web-Entwickler werden
JavaScript ist eine der populärsten Programmiersprachen und unersetzlich für Web-Entwickler. Hier erfahrt Ihr, warum Ihr unbedingt JavaScript lernen solltet.