Переглянути джерело

fix(types): ensure correct type for toRef and toRefs on existing refs

Evan You 5 роки тому
батько
коміт
8e20375372
2 змінених файлів з 22 додано та 6 видалено
  1. 4 5
      packages/reactivity/src/ref.ts
  2. 18 1
      test-dts/ref.test-d.ts

+ 4 - 5
packages/reactivity/src/ref.ts

@@ -20,7 +20,8 @@ export interface Ref<T = any> {
   _shallow?: boolean
 }
 
-export type ToRefs<T = any> = { [K in keyof T]: Ref<T[K]> }
+export type ToRef<T> = T extends Ref ? T : Ref<UnwrapRef<T>>
+export type ToRefs<T = any> = { [K in keyof T]: ToRef<T[K]> }
 
 const convert = <T extends unknown>(val: T): T =>
   isObject(val) ? reactive(val) : val
@@ -30,9 +31,7 @@ export function isRef(r: any): r is Ref {
   return Boolean(r && r.__v_isRef === true)
 }
 
-export function ref<T extends object>(
-  value: T
-): T extends Ref ? T : Ref<UnwrapRef<T>>
+export function ref<T extends object>(value: T): ToRef<T>
 export function ref<T>(value: T): Ref<UnwrapRef<T>>
 export function ref<T = any>(): Ref<T | undefined>
 export function ref(value?: unknown) {
@@ -171,7 +170,7 @@ class ObjectRefImpl<T extends object, K extends keyof T> {
 export function toRef<T extends object, K extends keyof T>(
   object: T,
   key: K
-): Ref<T[K]> {
+): ToRef<T[K]> {
   return isRef(object[key])
     ? object[key]
     : (new ObjectRefImpl(object, key) as any)

+ 18 - 1
test-dts/ref.test-d.ts

@@ -6,7 +6,9 @@ import {
   unref,
   reactive,
   expectType,
-  proxyRefs
+  proxyRefs,
+  toRef,
+  toRefs
 } from './index'
 
 function plainType(arg: number | Ref<number>) {
@@ -154,3 +156,18 @@ const r2 = {
 const p2 = proxyRefs(r2)
 expectType<number>(p2.a)
 expectType<Ref<string>>(p2.obj.k)
+
+// toRef
+const obj = {
+  a: 1,
+  b: ref(1)
+}
+expectType<Ref<number>>(toRef(obj, 'a'))
+expectType<Ref<number>>(toRef(obj, 'b'))
+
+// toRefs
+const objRefs = toRefs(obj)
+expectType<{
+  a: Ref<number>
+  b: Ref<number>
+}>(objRefs)