Skip to content

Props/Emits タイピング

11.2.1. defineProps タイピング

Props はジェネリック構文 defineProps<T>() を使用してタイピングします。ランタイム宣言方式は使用しません。

vue
<script setup lang="ts">
defineProps<{
  title: string
  count: number
  isActive: boolean
}>()
</script>

Props プロパティが3つを超える場合、別途 interface に分離します。

vue
<script setup lang="ts">
interface UserCardProps {
  userId: number
  name: string
  email: string
  role: string
  avatarUrl?: string
}

const props = defineProps<UserCardProps>()
</script>

11.2.2. withDefaults

Props のデフォルト値は withDefaults を使用します。オブジェクトまたは配列型のデフォルト値は必ずファクトリ関数を使用します。

vue
<script setup lang="ts">
interface NotificationProps {
  message: string
  type?: 'info' | 'warning' | 'error'
  duration?: number
  actions?: string[]
}

const props = withDefaults(defineProps<NotificationProps>(), {
  type: 'info',
  duration: 3000,
  actions: () => [],
})
</script>
  • 基本型(string, number, boolean)は値を直接代入します。
  • オブジェクト、配列型はファクトリ関数を使用してインスタンス間の参照共有を防止します。

11.2.3. defineEmits タイピング

Emits はジェネリック構文でイベントシグネチャを定義します。ペイロード型を必ず明示します。

vue
<script setup lang="ts">
const emit = defineEmits<{
  search: [filters: { keyword: string; category: string }]
  reset: []
  select: [id: number, label: string]
}>()

function handleSearch(keyword: string, category: string) {
  emit('search', { keyword, category })
}
</script>
  • ペイロードのないイベントは空の配列 [] で定義します。
  • ペイロードが2つ以上の場合、ラベルを付与して可読性を確保します。

11.2.4. 複雑な Props パターン

ユニオン Props はコンポーネントの動作モードを分岐する際に使用します。

vue
<script setup lang="ts">
type ButtonProps =
  | { variant: 'link'; href: string; disabled?: boolean }
  | { variant: 'button'; onClick: () => void; disabled?: boolean }

const props = defineProps<ButtonProps>()
</script>

v-model PropsmodelValueupdate:modelValue のペアで定義します。

vue
<script setup lang="ts">
const props = defineProps<{ modelValue: string; placeholder?: string }>()
const emit = defineEmits<{ 'update:modelValue': [value: string] }>()
</script>

条件付き必須 Props は判別プロパティに応じて他のプロパティが必須になるパターンです。

vue
<script setup lang="ts">
type ModalProps =
  | { mode: 'confirm'; onConfirm: () => void; onCancel: () => void }
  | { mode: 'alert'; onConfirm: () => void }

const props = defineProps<ModalProps>()
</script>
  • 過度に複雑なユニオン Props はコンポーネントの分離を検討します。

TIENIPIA QUALIFIED STANDARD