feat(reactivity): ref(Ref) should return Ref (#180)
This commit is contained in:
parent
80f5cb2700
commit
cbb4b19cfb
@ -1,3 +1,4 @@
|
||||
import { ref, isRef } from '../src/ref'
|
||||
import { reactive, isReactive, toRaw, markNonReactive } from '../src/reactive'
|
||||
import { mockWarn } from '@vue/runtime-test'
|
||||
|
||||
@ -126,6 +127,14 @@ describe('reactivity/reactive', () => {
|
||||
expect(toRaw(original)).toBe(original)
|
||||
})
|
||||
|
||||
test('should not unwrap Ref<T>', () => {
|
||||
const observedNumberRef = reactive(ref(1))
|
||||
const observedObjectRef = reactive(ref({ foo: 1 }))
|
||||
|
||||
expect(isRef(observedNumberRef)).toBe(true)
|
||||
expect(isRef(observedObjectRef)).toBe(true)
|
||||
})
|
||||
|
||||
test('non-observable values', () => {
|
||||
const assertValue = (value: any) => {
|
||||
reactive(value)
|
||||
|
@ -63,6 +63,13 @@ describe('reactivity/ref', () => {
|
||||
expect(dummy3).toBe(3)
|
||||
})
|
||||
|
||||
it('should unwrap nested ref in types', () => {
|
||||
const a = ref(0)
|
||||
const b = ref(a)
|
||||
|
||||
expect(typeof (b.value + 1)).toBe('number')
|
||||
})
|
||||
|
||||
it('should unwrap nested values in types', () => {
|
||||
const a = {
|
||||
b: ref(0)
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { effect, ReactiveEffect, activeReactiveEffectStack } from './effect'
|
||||
import { Ref, refSymbol, UnwrapNestedRefs } from './ref'
|
||||
import { Ref, refSymbol, UnwrapRef } from './ref'
|
||||
import { isFunction, NOOP } from '@vue/shared'
|
||||
|
||||
export interface ComputedRef<T> extends WritableComputedRef<T> {
|
||||
readonly value: UnwrapNestedRefs<T>
|
||||
readonly value: UnwrapRef<T>
|
||||
}
|
||||
|
||||
export interface WritableComputedRef<T> extends Ref<T> {
|
||||
|
@ -7,14 +7,15 @@ export const refSymbol = Symbol(__DEV__ ? 'refSymbol' : undefined)
|
||||
|
||||
export interface Ref<T = any> {
|
||||
[refSymbol]: true
|
||||
value: UnwrapNestedRefs<T>
|
||||
value: UnwrapRef<T>
|
||||
}
|
||||
|
||||
export type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRef<T>
|
||||
|
||||
const convert = (val: any): any => (isObject(val) ? reactive(val) : val)
|
||||
|
||||
export function ref<T>(raw: T): Ref<T> {
|
||||
if (isRef(raw)) {
|
||||
return raw
|
||||
}
|
||||
raw = convert(raw)
|
||||
const v = {
|
||||
[refSymbol]: true,
|
||||
@ -48,16 +49,15 @@ function toProxyRef<T extends object, K extends keyof T>(
|
||||
object: T,
|
||||
key: K
|
||||
): Ref<T[K]> {
|
||||
const v = {
|
||||
return {
|
||||
[refSymbol]: true,
|
||||
get value() {
|
||||
get value(): any {
|
||||
return object[key]
|
||||
},
|
||||
set value(newVal) {
|
||||
object[key] = newVal
|
||||
}
|
||||
}
|
||||
return v as Ref<T[K]>
|
||||
}
|
||||
|
||||
type BailTypes =
|
||||
@ -80,3 +80,6 @@ export type UnwrapRef<T> = {
|
||||
: T extends BailTypes
|
||||
? 'stop' // bail out on types that shouldn't be unwrapped
|
||||
: T extends object ? 'object' : 'stop']
|
||||
|
||||
// only unwrap nested ref
|
||||
export type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRef<T>
|
||||
|
Loading…
Reference in New Issue
Block a user