In the Quantum Laboratory, every station module must precisely declare what data it accepts. In Vue 3 with TypeScript, we use the generic syntax
defineProps<{}>() to type props.Instead of runtime validation (object with
type, required), we can use TypeScript syntax:1<script setup lang="ts">
2// Generic syntax — types checked at compile time
3const props = defineProps<{
4 title: string
5 count: number
6 isActive: boolean
7}>()
8</script>This is equivalent to the traditional syntax:
1<script setup>
2// Old syntax — runtime validation
3const props = defineProps({
4 title: { type: String, required: true },
5 count: { type: Number, required: true },
6 isActive: { type: Boolean, required: true }
7})
8</script>When a component has many props, it's worth extracting an interface:
1<script setup lang="ts">
2interface StationModuleProps {
3 name: string
4 status: 'online' | 'offline' | 'maintenance'
5 powerLevel: number
6 crew?: string[] // optional prop (?)
7}
8
9const props = defineProps<StationModuleProps>()
10</script>The
? sign means the prop is optional — it doesn't have to be passed.TypeScript generics don't allow default values in
defineProps. That's what withDefaults is for: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>Now
props.variant will be 'primary' if not provided.TypeScript allows defining precise types:
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>Props can contain nested objects and arrays:
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> is a dictionary type — an object with string keys and values of any type.