TypeScript 与 Vue 3:类型安全实践
TypeScript 与 Vue 3:类型安全实践
TypeScript 为 Vue 3 项目提供类型检查,减少运行时错误。这篇说说在 Vue 中用 TypeScript 的常见场景。
Props 类型推导
Vue 3 的 defineProps 能自动推导类型:
<script setup lang="ts">
// 自动推导
const props = defineProps<{
name: string
age: number
email?: string // 可选
}>()
// 使用
console.log(props.name)
</script>
带默认值:
withDefaults(defineProps<{
name: string
age?: number
}>(), {
age: 0
})
组件事件类型
<script setup lang="ts">
const emit = defineEmits<{
(e: 'update', value: string): void
(e: 'delete', id: number): void
}>()
emit('update', 'new value')
</script>
ref 类型
// TypeScript 自动推导
const count = ref(0) // Ref<number>
const name = ref('张三') // Ref<string>
// 手动指定
const el = ref<HTMLElement | null>(null)
const list = ref<User[]>([])
reactive 类型
// 手动指定类型
const user = reactive<User>({
name: '张三',
age: 25
})
泛型组件
有时组件需要处理任意类型的数据:
<script setup lang="ts" generic="T">
defineProps<{
items: T[]
selected: T
}>()
</script>
使用:
<ItemList :items="stringList" :selected="selectedString" />
<ItemList :items="numberList" :selected="selectedNumber" />
常用类型定义
// 接口
interface User {
id: number
name: string
email: string
}
// 类型别名
type Status = 'pending' | 'success' | 'error'
// 枚举
enum Gender {
Male,
Female
}
// 联合类型
type ID = string | number
常见错误处理
类型守卫
function isUser(obj: unknown): obj is User {
return typeof obj === 'object' && obj !== null && 'name' in obj
}
if (isUser(data)) {
console.log(data.name)
}
非空断言
确定值存在时用 !:
const el = document.getElementById('app')
el!.style.color = 'red'
类型收窄
function handleClick(id: string | number) {
if (typeof id === 'string') {
console.log(id.toUpperCase())
} else {
console.log(id.toFixed(2))
}
}
Pinia 中使用 TypeScript
import { defineStore } from 'pinia'
interface UserState {
name: string
age: number
}
export const useUserStore = defineStore('user', {
state: (): UserState => ({
name: '',
age: 0
}),
getters: {
isAdult: (state): boolean => state.age >= 18
},
actions: {
setUser(name: string, age: number) {
this.name = name
this.age = age
}
}
})
总结
defineProps<{ ... }>()自动推导 props 类型defineEmits<{ ... }>()定义带类型的事件ref<T>()和reactive<T>()指定类型- TypeScript 让代码更健壮,IDE 提示更准确
进阶技巧阶段结束,下篇开始项目实战阶段。
