From 1c56d1bf19e91731d5e2e4d8f47a76b95bb24255 Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 14 Oct 2019 11:21:09 -0400 Subject: [PATCH] test: test unwrapping computed refs --- .../reactivity/__tests__/reactive.spec.ts | 17 ++++++++++++++ packages/reactivity/src/reactive.ts | 7 +++--- packages/reactivity/src/ref.ts | 22 +++++++------------ 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/packages/reactivity/__tests__/reactive.spec.ts b/packages/reactivity/__tests__/reactive.spec.ts index 8743d78c8..2d134922d 100644 --- a/packages/reactivity/__tests__/reactive.spec.ts +++ b/packages/reactivity/__tests__/reactive.spec.ts @@ -1,6 +1,7 @@ import { ref, isRef } from '../src/ref' import { reactive, isReactive, toRaw, markNonReactive } from '../src/reactive' import { mockWarn } from '@vue/runtime-test' +import { computed } from '../src/computed' describe('reactivity/reactive', () => { mockWarn() @@ -135,6 +136,22 @@ describe('reactivity/reactive', () => { expect(isRef(observedObjectRef)).toBe(true) }) + test('should unwrap computed refs', () => { + // readonly + const a = computed(() => 1) + // writable + const b = computed({ + get: () => 1, + set: () => {} + }) + const obj = reactive({ a, b }) + // check type + obj.a + 1 + obj.b + 1 + expect(typeof obj.a).toBe(`number`) + expect(typeof obj.b).toBe(`number`) + }) + test('non-observable values', () => { const assertValue = (value: any) => { reactive(value) diff --git a/packages/reactivity/src/reactive.ts b/packages/reactivity/src/reactive.ts index 5fba51247..2d55e2159 100644 --- a/packages/reactivity/src/reactive.ts +++ b/packages/reactivity/src/reactive.ts @@ -1,13 +1,11 @@ import { isObject, toTypeString } from '@vue/shared' import { mutableHandlers, readonlyHandlers } from './baseHandlers' - import { mutableCollectionHandlers, readonlyCollectionHandlers } from './collectionHandlers' - -import { UnwrapNestedRefs } from './ref' import { ReactiveEffect } from './effect' +import { UnwrapRef, Ref } from './ref' // The main WeakMap that stores {target -> key -> dep} connections. // Conceptually, it's easier to think of a dependency as a Dep class @@ -40,6 +38,9 @@ const canObserve = (value: any): boolean => { ) } +// only unwrap nested ref +type UnwrapNestedRefs = T extends Ref ? T : UnwrapRef + export function reactive(target: T): UnwrapNestedRefs export function reactive(target: object) { // if trying to observe a readonly proxy, return the readonly version. diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index 07953e0bf..7fec6ffbf 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -2,7 +2,7 @@ import { track, trigger } from './effect' import { OperationTypes } from './operations' import { isObject } from '@vue/shared' import { reactive } from './reactive' -import { ComputedRef, WritableComputedRef } from './computed' +import { ComputedRef } from './computed' export const refSymbol = Symbol(__DEV__ ? 'refSymbol' : '') @@ -73,22 +73,16 @@ type BailTypes = // Recursively unwraps nested value bindings. export type UnwrapRef = { cRef: T extends ComputedRef ? UnwrapRef : T - wcRef: T extends WritableComputedRef ? UnwrapRef : T ref: T extends Ref ? UnwrapRef : T array: T extends Array ? Array> : T object: { [K in keyof T]: UnwrapRef } stop: T }[T extends ComputedRef ? 'cRef' - : T extends WritableComputedRef - ? 'wcRef' - : T extends Ref - ? 'ref' - : T extends Array - ? 'array' - : 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 extends Ref ? T : UnwrapRef + : T extends Ref + ? 'ref' + : T extends Array + ? 'array' + : T extends BailTypes + ? 'stop' // bail out on types that shouldn't be unwrapped + : T extends object ? 'object' : 'stop']