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