From e315d84936c82bee8f2cf2369c61b5aaec38f328 Mon Sep 17 00:00:00 2001 From: Evan You Date: Wed, 2 Dec 2020 14:58:03 -0500 Subject: [PATCH] fix(types): fix ToRefs type on union value types fix #2687 --- packages/reactivity/src/ref.ts | 6 +++++- test-dts/ref.test-d.ts | 27 +++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/reactivity/src/ref.ts b/packages/reactivity/src/ref.ts index e3633f98..ac3016d3 100644 --- a/packages/reactivity/src/ref.ts +++ b/packages/reactivity/src/ref.ts @@ -21,7 +21,11 @@ export interface Ref { } export type ToRef = T extends Ref ? T : Ref> -export type ToRefs = { [K in keyof T]: ToRef } +export type ToRefs = { + // #2687: somehow using ToRef here turns the resulting type into + // a union of multiple Ref<*> types instead of a single Ref<* | *> type. + [K in keyof T]: T[K] extends Ref ? T[K] : Ref> +} const convert = (val: T): T => isObject(val) ? reactive(val) : val diff --git a/test-dts/ref.test-d.ts b/test-dts/ref.test-d.ts index f736977b..83589f93 100644 --- a/test-dts/ref.test-d.ts +++ b/test-dts/ref.test-d.ts @@ -8,7 +8,8 @@ import { expectType, proxyRefs, toRef, - toRefs + toRefs, + ToRefs } from './index' function plainType(arg: number | Ref) { @@ -28,7 +29,6 @@ function plainType(arg: number | Ref) { const nestedRef = ref({ foo: ref(1) }) - expectType>(nestedRef) expectType<{ foo: number }>(nestedRef.value) // ref boolean @@ -171,3 +171,26 @@ expectType<{ a: Ref b: Ref }>(objRefs) + +// #2687 +interface AppData { + state: 'state1' | 'state2' | 'state3' +} + +const data: ToRefs = toRefs( + reactive({ + state: 'state1' + }) +) + +switch (data.state.value) { + case 'state1': + data.state.value = 'state2' + break + case 'state2': + data.state.value = 'state3' + break + case 'state3': + data.state.value = 'state1' + break +}