Vite로 Vue 3 + TypeScript 프로젝트 생성
npm create vite@latest my-app -- --template vue-ts
cd my-app && npm install
defineProps에 타입 지정
<script setup lang="ts">
// 방법 1: 타입 기반 (권장)
interface Props {
title: string
count?: number
tags: string[]
}
const props = defineProps<Props>()
// 방법 2: 기본값 포함
const props = withDefaults(defineProps<Props>(), {
count: 0,
tags: () => [],
})
</script>
defineEmits에 타입 지정
<script setup lang="ts">
const emit = defineEmits<{
submit: [payload: { name: string; age: number }]
cancel: []
}>()
emit('submit', { name: 'Hoon', age: 30 })
</script>
ref 타입 지정
import { ref } from 'vue'
const count = ref<number>(0)
const user = ref<{ name: string; age: number } | null>(null)
const items = ref<string[]>([])
reactive 타입 지정
import { reactive } from 'vue'
interface User {
name: string
age: number
email: string
}
const user = reactive<User>({
name: 'Hoon',
age: 30,
email: 'hoon@example.com',
})
computed 타입 지정
import { ref, computed } from 'vue'
const count = ref(0)
const doubleCount = computed<number>(() => count.value * 2)
Template Ref 타입 지정
<script setup lang="ts">
import { ref, onMounted } from 'vue'
const inputEl = ref<HTMLInputElement | null>(null)
onMounted(() => {
inputEl.value?.focus()
})
</script>
<template>
<input ref="inputEl" />
</template>
API 응답 타입 정의
// types/api.ts
export interface Post {
id: number
title: string
content: string
createdAt: string
}
// composables/usePost.ts
import type { Post } from '@/types/api'
async function fetchPost(id: number): Promise<Post> {
const res = await fetch(`/api/posts/${id}`)
return res.json() as Promise<Post>
}
tsconfig.json 권장 설정
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true,
"jsx": "preserve",
"moduleResolution": "bundler",
"paths": {
"@/*": ["./src/*"]
}
}
}