We use cookies to enhance your experience on the site
CodeWorlds

Typing Props

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.

defineProps with Generic Type

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>

Extracting an Interface

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.

withDefaults

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.

Union Types in Props

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>

Complex Prop Types

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.

Go to CodeWorlds