From d4c6957e2d8ac7920a649f3a3576689cd5e1099f Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 25 Feb 2020 19:44:06 -0500 Subject: [PATCH] fix(types): ref value type unwrapping should happen at creation time --- packages/reactivity/src/computed.ts | 4 ++-- packages/reactivity/src/ref.ts | 6 +++--- test-dts/ref.test-d.ts | 6 ++++++ test-dts/watch.test-d.ts | 10 ++++++++++ 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/reactivity/src/computed.ts b/packages/reactivity/src/computed.ts index 1a64bdf2..154247a6 100644 --- a/packages/reactivity/src/computed.ts +++ b/packages/reactivity/src/computed.ts @@ -1,10 +1,10 @@ import { effect, ReactiveEffect, trigger, track } from './effect' import { TriggerOpTypes, TrackOpTypes } from './operations' -import { Ref, UnwrapRef } from './ref' +import { Ref } from './ref' import { isFunction, NOOP } from '@vue/shared' export interface ComputedRef extends WritableComputedRef { - readonly value: UnwrapRef + readonly value: T } export interface WritableComputedRef extends Ref { diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index f8863113..dde3b82b 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -17,7 +17,7 @@ export interface Ref { // don't want this internal field to leak into userland autocompletion - // a private symbol, on the other hand, achieves just that. [isRefSymbol]: true - value: UnwrapRef + value: T } const convert = (val: T): T => @@ -28,13 +28,13 @@ export function isRef(r: any): r is Ref { return r ? r._isRef === true : false } -export function ref(value: T): T extends Ref ? T : Ref +export function ref(value: T): T extends Ref ? T : Ref> export function ref(): Ref export function ref(value?: unknown) { return createRef(value) } -export function shallowRef(value: T): T extends Ref ? T : Ref +export function shallowRef(value: T): T extends Ref ? T : Ref> export function shallowRef(): Ref export function shallowRef(value?: unknown) { return createRef(value, true) diff --git a/test-dts/ref.test-d.ts b/test-dts/ref.test-d.ts index e1323fef..1ae7c355 100644 --- a/test-dts/ref.test-d.ts +++ b/test-dts/ref.test-d.ts @@ -13,6 +13,12 @@ function foo(arg: number | Ref) { // ref unwrapping expectType(unref(arg)) + + // ref inner type should be unwrapped + const nestedRef = ref({ + foo: ref(1) + }) + expectType>(nestedRef) } foo(1) diff --git a/test-dts/watch.test-d.ts b/test-dts/watch.test-d.ts index 7f49691c..c532bc2b 100644 --- a/test-dts/watch.test-d.ts +++ b/test-dts/watch.test-d.ts @@ -52,3 +52,13 @@ watch( }, { immediate: true } ) + +// should provide correct ref.value inner type to callbacks +const nestedRefSource = ref({ + foo: ref(1) +}) + +watch(nestedRefSource, (v, ov) => { + expectType<{ foo: number }>(v) + expectType<{ foo: number }>(ov) +})