Cours Vue.js · Module 15: TypeScript et Nuxt
Typer les props
Dans cette leçon5
Dans le Laboratoire Quantique, chaque module de la station doit déclarer précisément quelles données il accepte. Dans Vue 3 avec TypeScript, on utilise la syntaxe générique defineProps<{}>() pour typer les props.
defineProps avec type générique
Au lieu d'une validation à l'exécution (objet avec type, required), on peut utiliser la syntaxe TypeScript :
1<script setup lang="ts">
2// Syntaxe générique - types vérifiés à la compilation
3const props = defineProps<{
4 title: string
5 count: number
6 isActive: boolean
7}>()
8</script>C'est l'équivalent de la syntaxe traditionnelle :
1<script setup>
2// Ancienne syntaxe - validation à l'exécution
3const props = defineProps({
4 title: { type: String, required: true },
5 count: { type: Number, required: true },
6 isActive: { type: Boolean, required: true }
7})
8</script>Extraire une interface
Quand un composant a beaucoup de props, il vaut mieux extraire une interface :
1<script setup lang="ts">
2interface StationModuleProps {
3 name: string
4 status: 'online' | 'offline' | 'maintenance'
5 powerLevel: number
6 crew?: string[] // prop optionnelle (?)
7}
8
9const props = defineProps<StationModuleProps>()
10</script>Le signe ? signifie que la prop est optionnelle - elle n'a pas besoin d'être transmise.
withDefaults
Les génériques de TypeScript ne permettent pas de définir des valeurs par défaut dans defineProps. C'est à ça que sert withDefaults :
1<script setup lang="ts">
2interface PanelProps {
3 title: string
4 variant?: 'primary' | 'danger' | 'success'
5 maxItems?: number
6 showHeader?: boolean
7}
8
9const props = withDefaults(defineProps<PanelProps>(), {
10 variant: 'primary',
11 maxItems: 10,
12 showHeader: true
13})
14</script>Maintenant props.variant vaudra 'primary' s'il n'est pas fourni.
Les types union dans les props
TypeScript permet de définir des types précis :
1<script setup lang="ts">
2type AlertLevel = 'info' | 'warning' | 'critical'
3
4interface AlertProps {
5 level: AlertLevel
6 message: string
7 code?: number
8}
9
10const props = defineProps<AlertProps>()
11</script>
12
13<template>
14 <div :class="['alert', props.level]">
15 {{ props.message }}
16 </div>
17</template>Types de props complexes
Les props peuvent contenir des objets imbriqués et des tableaux :
1<script setup lang="ts">
2interface Coordinate {
3 x: number
4 y: number
5 z: number
6}
7
8interface SensorData {
9 id: string
10 location: Coordinate
11 readings: number[]
12 metadata?: Record<string, unknown>
13}
14
15interface SensorPanelProps {
16 sensors: SensorData[]
17 selectedId: string | null
18 onSelect?: (id: string) => void
19}
20
21const props = defineProps<SensorPanelProps>()
22</script>Record<string, unknown> est un type dictionnaire - un objet avec des clés de type chaîne et des valeurs de n'importe quel type.
Code de cette leçon : App.vue
1<script setup lang="ts">
2import { ref } from 'vue'
3import ModuleCard from './ModuleCard.vue'
4
5interface StationModule {
6 id: string
7 name: string
8 status: 'online' | 'offline' | 'maintenance'
9 power: number
10}
11
12const modules = ref<StationModule[]>([
13 { id: 'm1', name: 'Life Support', status: 'online', power: 95 },
14 { id: 'm2', name: 'Navigation', status: 'online', power: 88 },
15 { id: 'm3', name: 'Science Lab', status: 'maintenance', power: 40 },
16 { id: 'm4', name: 'Communications', status: 'offline', power: 0 }
17])
18</script>
19
20<template>
21 <div class="nova-lab">
22 <h1>NOVA LAB - Props typées</h1>
23 <ModuleCard
24 v-for="mod in modules"
25 :key="mod.id"
26 :module="mod"
27 :show-power="true"
28 />
29 </div>
30</template>
31
32<style scoped>
33.nova-lab {
34 background: #0a0e27;
35 color: #00ff88;
36 min-height: 100vh;
37 padding: 20px;
38 font-family: monospace;
39}
40h1 { color: #00ff88; margin-bottom: 15px; }
41</style>Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Quelle syntaxe définit des props typées dans Vue 3 avec TypeScript ?
2. Comment marque-t-on une prop comme optionnelle dans une interface TypeScript ?
Voici 2 des 3 questions de cette leçon. Réponds aux autres dans le jeu.
Tâches pratiques dans le jeu
- Éditeur de code
Utilise withDefaults(defineProps<Props>(), { ... }) pour définir des valeurs par défaut.
- Tri horizontal
Ordonne la syntaxe correcte de withDefaults avec defineProps :
- Éditeur de code
Utilise defineEmits<{}> pour définir un événement 'command' avec des arguments typés.