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 Props는 modelValue와 update: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는 컴포넌트 분리를 고려합니다.