vue3 中的工具类型总结 UnwrapRef

275 阅读2分钟

困惑我好久了这代码,我ts白痴,我不刻印脑子里我不叫小old弟:

function ref<T>(value: T): Ref<UnwrapRef<T>>

interface Ref<T>{
  value: T
}

Vue3 Composition APIref函数的类型定义。

用来创建一个响应式引用(Reactive Reference)


ref<T>(value: T): Ref<UnwrapRef<T>>

ref 函数的 类型签名。

  • <T>: 泛型参数,表示传入的值类型
  • value: Tref接收一个任意类型的值value
  • Ref<UnwrapRef<T>>:返回一个Ref对象,其内部值value的类型是UnwrapRef<T>

UnwrapRef<T>递归解包嵌套的Ref类型

  • 如果T本身是一个Ref,比如Ref<number>,那么UnwrapRef<T>会提取出number

  • 如果T是一个对象,并且某些属性是Ref,它们会被解包成原始类型。

示例:

const numRef = ref(10); // Ref<number>
const objRef = ref({ count: 1 });; // Ref<{ count: number }>

interface Ref<T>

Ref是一个接口:

interface Ref<T> {
  value: T
}
  • valueRef的核心属性,访问或修改它时会触发Vue的响应式更新。

  • T是存储的值的类型。

import { ref } from 'vue';

// 创建一个 Ref<number>
const count = ref(0);

// 访问值
console.log(count.value); // 0

// 修改值 (会触发响应式更新)
count.value = 10;

UnwrapRef<T>嵌套

vue3 的 响应式系统会 自动解包嵌套的Ref,所以UnwrapRef确保类型正确匹配运行时行为。

const innerRef = ref(10);
const outerRef = ref(innerRef); // Ref<number>而不是Ref<Ref<number>>
  • 运行时,outerRef.value直接是number(不是Ref<number>
  • UnwrapRef确保类型系统知道这一点。
import { ref } from 'vue';

// 1. ref(10) -> Ref<number>
const count = ref(10);

// 2. ref({ count: ref(1) }) -> Ref<{ count: number }> (自动解包)
const obj = ref({
  count: ref(1), //  嵌套 Ref 会被解包
});

console.log(obj.value.count); // 1 (不是 Ref,而是 number)

总结

  • ref(value) 返回一个 Ref 对象,其 .value 属性是响应式的。

  • UnwrapRef<T> 确保嵌套的 Ref 被正确解包,使类型系统匹配 Vue 的运行时行为。

  • Ref<T> 是一个简单的接口,包含 value: T,用于存储响应式值。

这在 Vue 3Composition API 中非常重要,因为它允许我们创建基本类型(如 number、string)的响应式变量,而 reactive() 仅适用于对象。