From 7c4e57f1a5c37edb2d2d235705035b3303c35e27 Mon Sep 17 00:00:00 2001 From: pikax Date: Mon, 4 May 2020 10:35:32 +0100 Subject: [PATCH 1/2] types: add test for unwrapRef `value` and rollback Ref.isRefSymbol symbol --- packages/reactivity/__tests__/reactive.spec.ts | 11 +++++++++++ packages/reactivity/src/ref.ts | 12 ++++++++++++ test-dts/ref.test-d.ts | 3 +++ 3 files changed, 26 insertions(+) diff --git a/packages/reactivity/__tests__/reactive.spec.ts b/packages/reactivity/__tests__/reactive.spec.ts index 44fc5391df1..c45dfee0cb8 100644 --- a/packages/reactivity/__tests__/reactive.spec.ts +++ b/packages/reactivity/__tests__/reactive.spec.ts @@ -129,6 +129,17 @@ describe('reactivity/reactive', () => { expect(typeof obj.b).toBe(`number`) }) + it('should not unwrap interface with `value` property', () => { + const o = { + a: 1, + value: { + b: 2 + } + } + const r = reactive(o) + expect(r.value.b).toMatchObject(o) + }) + test('non-observable values', () => { const assertValue = (value: any) => { reactive(value) diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index 629a2dad9b0..94645f2d42a 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -5,11 +5,23 @@ import { reactive, isProxy, toRaw } from './reactive' import { ComputedRef } from './computed' import { CollectionTypes } from './collectionHandlers' +declare const isRefSymbol: unique symbol export interface Ref { + // This field is necessary to allow TS to differentiate a Ref from a plain + // object that happens to have a "value" field. + // However, checking a symbol on an arbitrary object is much slower than + // checking a plain property, so we use a __v_isRef plain property for isRef() + // check in the actual implementation. + // The reason for not just declaring __v_isRef in the interface is because we + // don't want this internal field to leak into userland autocompletion - + // a private symbol, on the other hand, achieves just that. + [isRefSymbol]: true + /** * @internal */ __v_isRef: true + value: T } diff --git a/test-dts/ref.test-d.ts b/test-dts/ref.test-d.ts index 41dc6ee75c4..d4d61090c08 100644 --- a/test-dts/ref.test-d.ts +++ b/test-dts/ref.test-d.ts @@ -42,6 +42,9 @@ function plainType(arg: number | Ref) { expectType>( ref() ) + + // with value + expect>(ref({ value: { a: 1 } })) } plainType(1) From ab2f335f785dd2514eaf2a6d40bb92cdc2920ded Mon Sep 17 00:00:00 2001 From: pikax Date: Mon, 4 May 2020 10:54:09 +0100 Subject: [PATCH 2/2] test: fix test --- packages/reactivity/__tests__/reactive.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/reactivity/__tests__/reactive.spec.ts b/packages/reactivity/__tests__/reactive.spec.ts index c45dfee0cb8..e85d5a2f42b 100644 --- a/packages/reactivity/__tests__/reactive.spec.ts +++ b/packages/reactivity/__tests__/reactive.spec.ts @@ -137,7 +137,7 @@ describe('reactivity/reactive', () => { } } const r = reactive(o) - expect(r.value.b).toMatchObject(o) + expect(r).toMatchObject(o) }) test('non-observable values', () => {