]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(types/ref): allow getter and setter types to be unrelated (#11442)
authorTycho <jh.leong@outlook.com>
Mon, 29 Jul 2024 02:52:38 +0000 (10:52 +0800)
committerGitHub <noreply@github.com>
Mon, 29 Jul 2024 02:52:38 +0000 (10:52 +0800)
packages/dts-test/ref.test-d.ts
packages/dts-test/watch.test-d.ts
packages/reactivity/src/ref.ts
packages/runtime-core/src/apiWatch.ts

index 1456c523239bda8a991ac4683d72ee28f032b610..46d39214b930758449c9c310073d65debea0e937 100644 (file)
@@ -172,6 +172,16 @@ describe('ref with generic', <T extends { name: string }>() => {
   expectType<string>(ss.value.name)
 })
 
+describe('allow getter and setter types to be unrelated', <T>() => {
+  const a = { b: ref(0) }
+  const c = ref(a)
+  c.value = a
+
+  const d = {} as T
+  const e = ref(d)
+  e.value = d
+})
+
 // shallowRef
 type Status = 'initial' | 'ready' | 'invalidating'
 const shallowStatus = shallowRef<Status>('initial')
index 45c898ef672ad50c5f07bdd64e4b19404a834910..6c8576f0c6ba6921c447590d56408355f1270a18 100644 (file)
@@ -1,5 +1,6 @@
 import {
   type ComputedRef,
+  type MaybeRef,
   type Ref,
   computed,
   defineComponent,
@@ -203,3 +204,10 @@ defineComponent({
     expectType<{ foo: string }>(value)
   })
 }
+
+{
+  const css: MaybeRef<string> = ''
+  watch(ref(css), value => {
+    expectType<string>(value)
+  })
+}
index 3e9b05062f3991dbfed7272afd4585716d82a954..6e22d1bcd58ca29a9fd10f3966db6542166a30ca 100644 (file)
@@ -30,8 +30,9 @@ import { warn } from './warning'
 declare const RefSymbol: unique symbol
 export declare const RawSymbol: unique symbol
 
-export interface Ref<T = any> {
-  value: T
+export interface Ref<T = any, S = T> {
+  get value(): T
+  set value(_: S)
   /**
    * Type differentiator only.
    * We need this to be in public d.ts but don't want it to show up in IDE
@@ -108,7 +109,7 @@ export function isRef(r: any): r is Ref {
  * @param value - The object to wrap in the ref.
  * @see {@link https://vuejs.org/api/reactivity-core.html#ref}
  */
-export function ref<T>(value: T): Ref<UnwrapRef<T>>
+export function ref<T>(value: T): Ref<UnwrapRef<T>, UnwrapRef<T> | T>
 export function ref<T = any>(): Ref<T | undefined>
 export function ref(value?: unknown) {
   return createRef(value, false)
index cdf8b8c888f1546f42d9cb95765bb77c4c57eb17..8b570bc28fa8f291c230baf0005a037d6a0de86a 100644 (file)
@@ -46,7 +46,7 @@ import { useSSRContext } from './helpers/useSsrContext'
 
 export type WatchEffect = (onCleanup: OnCleanup) => void
 
-export type WatchSource<T = any> = Ref<T> | ComputedRef<T> | (() => T)
+export type WatchSource<T = any> = Ref<T, any> | ComputedRef<T> | (() => T)
 
 export type WatchCallback<V = any, OV = any> = (
   value: V,