TypeScript Vue3 类型怎么写
你有没有过写 Vue3 代码时,因为传错参数类型,运行时才弹红框报错的经历?比如给用户列表接口传了字符串的页码,或者给表单组件塞了数字类型的手机号?其实用 TypeScript 给 Vue3 写类型,能提前把这类“隐形坑”堵上,就像给代码加了个靠谱的“质检员”,不用等到跑起来才慌。
给组件 Props 写类型:别再用 any 当“万能补丁”
Props 是组件对外的接口,写对类型就能保证父组件传过来的值不会乱。很多新手会直接用 any 应付,结果相当于没加校验。举个例子:要做一个用户卡片组件,需要传 name(字符串)、age(数字)、isVip(布尔值)三个参数,用 Vue3 + TS 写的话,不用复杂语法,直接定义类型就行:

`typescript
// 先写一个Props类型,像给组件列“需求清单”
type UserCardProps = {
name: string;
age: number;
isVip: boolean;
// 加?就是选填,比如可选的头像url
avatarUrl?: string;
};
// 组件里用defineProps接收类型
const props = defineProps<UserCardProps>();
`
这样父组件传值时,要是把 age 写成字符串,VS Code 会直接标红提示,不用等到浏览器报错。如果是更灵活的场景,比如 Props 可以是字符串或数字的混合,也能用联合类型,比如 id: string | number,相当于告诉 TS:“这个值两种类型都认,但别传别的”。
给组件 Emits 写类型:提前约定“触发规则”
组件的自定义事件(Emits)也能加类型,避免子组件传错参数给父组件。比如子组件有个“点击删除”的事件,需要传要删的用户ID,类型该怎么写?
`typescript
// 定义Emits的参数类型,格式是(事件名,参数类型)
type UserCardEmits = {
// delete事件,参数是string/number类型的id
(e: 'delete', id: string | number): void;
};
// 用defineEmits接收类型
const emit = defineEmits<UserCardEmits>();
// 触发事件时,必须传对应类型的参数,比如emit('delete', 123)就对,传字符串'123'也对,但传布尔值就会标红
`
很多人忽略 Emits 的类型,结果子组件传了个数组当ID,父组件接的时候还要转类型,加了类型后,这一步也能省了。
给响应式数据(ref/reactive)写类型:不让数据“变味”
Vue3 的响应式 API 里,ref 经常会自动推断类型,但遇到复杂场景,比如初始值是 null,或者要存特定结构的对象,就得手动指定类型。比如要做一个搜索功能,searchData 初始是空,要存 keyword(字符串)和 isLoading(布尔值),要是直接写 ref({}),TS 会以为它是任意对象,容易误加属性。正确写法:
`typescript
// 先定义数据结构类型
type SearchData = {
keyword: string;
isLoading: boolean;
};
// ref的泛型就是指定它的类型,初始值可以补全结构,哪怕是空的也符合类型
const searchData = ref<SearchData>({
keyword: '',
isLoading: false
});
`
如果用 reactive,类型写法和上面类似,比如 const userInfo = reactive<UserInfo>({}),能保证响应式数据的每个属性都符合预期,不会出现“突然多了个不存在的属性”这种低级错误。
给组合式函数(Composables)写类型:多人协作不打架
如果用 Vue3 的组合式函数(比如封装的获取用户信息的 useUser),也可以加类型,让其他开发者用的时候不用看源码。比如 useUser 要返回 user(用户对象)和 fetchUser(获取用户的方法),写法:
`typescript
// 先定义返回值的类型
type UseUserReturn = {
user: UserCardProps | null;
fetchUser: (userId: string | number) => Promise<void>;
};
// 组合式函数里指定返回类型
function useUser(): UseUserReturn {
// 内部逻辑省略,返回符合类型的对象
const user = ref<UserCardProps | null>(null);
const fetchUser = async (id: string | number) => {
// 请求接口...
};
return { user, fetchUser };
}
`
这样其他开发者用 const { user, fetchUser } = useUser() 时,VS Code 会自动提示有哪些属性和方法,不用猜“这个变量到底是什么类型”。
其实 TypeScript 给 Vue3 写类型,核心就是“给每个需要约束的部分定好规则”——Props 是组件对外的规则,Emits 是组件事件的规则,响应式数据是内部状态的规则,组合式函数是复用逻辑的规则,就像给每样东西贴个标签,既省心又避免出错。