联合类型 ref 允许 .value 持有多种互斥类型之一,适用于表单状态切换、api 响应不统一等场景;定义时直接将联合类型作为 ref() 泛型参数,如 ref('loading')。

Ref 联合类型,本质是让 ref 的 .value 可以合法持有多种互斥的类型之一,而不是固定为某一种。这在表单状态切换(如“加载中|成功|失败”)、API 响应结构不统一、或 UI 组件支持多态数据时非常实用。
联合类型 ref 的定义方式
直接把联合类型作为泛型参数传给 ref() 即可。TypeScript 会自动推导 .value 的类型为该联合类型:
-
显式声明(推荐,意图清晰):
const status = ref('loading'); -
依赖类型推导(简洁,适用于初始值明确):
const status = ref('loading' as const);—— 但注意这样只会得到字面量类型'loading',不是联合类型;需写成:const status = ref('loading');或const status = ref<string>('loading') as Ref;</string>(不推荐强制断言)
处理复杂对象的联合类型 ref
当响应式值可能是不同结构的对象时,联合类型同样适用。例如一个异步请求结果可能为空、正在加载、或携带数据:
- 先定义类型:
type ApiResponse = { data: User[] } | { error: string } | null; - 再创建 ref:
const result = ref<apiresponse>(null);</apiresponse> - 使用时需类型守卫判断:
if (result.value && 'data' in result.value) { /* 处理成功 */ }else if (result.value && 'error' in result.value) { /* 处理错误 */ }
与可选类型、undefined 的区别
联合类型 T | U 和可选类型 T | undefined 不同:
-
ref<string number>('hello')</string>:允许赋值为字符串或数字,.value永远不会是undefined(除非你显式写ref<string number undefined>()</string>) -
ref<string>()</string>:等价于ref<string undefined>()</string>,因为无初始值时默认补undefined,此时.value可能为undefined - 若需“有值或无值 + 多种有值形态”,应组合使用:
ref(null)
模板中安全使用的提示
Vue 模板会自动解包 ref,但联合类型本身不改变运行时行为。要在模板中安全访问属性,建议:
- 用
v-if/v-else-if区分不同状态分支 - 避免直接访问可能不存在的属性(如
{{ data.user.name }}),先确保data是具体类型 - 配合
computed封装带类型守卫的派生状态,提升模板可读性










