)
}
+export declare const ShallowReactiveMarker: unique symbol
+
+export type ShallowReactive<T> = T & { [ShallowReactiveMarker]?: true }
+
/**
* Return a shallowly-reactive copy of the original object, where only the root
* level properties are reactive. It also does not auto-unwrap refs (even at the
* root level).
*/
-export function shallowReactive<T extends object>(target: T): T {
+export function shallowReactive<T extends object>(
+ target: T
+): ShallowReactive<T> {
return createReactiveObject(
target,
false,
import { isTracking, trackEffects, triggerEffects } from './effect'
import { TrackOpTypes, TriggerOpTypes } from './operations'
import { isArray, hasChanged } from '@vue/shared'
-import { isProxy, toRaw, isReactive, toReactive } from './reactive'
+import {
+ isProxy,
+ toRaw,
+ isReactive,
+ toReactive,
+ ShallowReactiveMarker
+} from './reactive'
import { CollectionTypes } from './collectionHandlers'
import { createDep, Dep } from './dep'
return createRef(value, false)
}
+declare const ShallowRefMarker: unique symbol
+
+type ShallowRef<T = any> = Ref<T> & { [ShallowRefMarker]?: true }
+
export function shallowRef<T extends object>(
value: T
-): T extends Ref ? T : Ref<T>
-export function shallowRef<T>(value: T): Ref<T>
-export function shallowRef<T = any>(): Ref<T | undefined>
+): T extends Ref ? T : ShallowRef<T>
+export function shallowRef<T>(value: T): ShallowRef<T>
+export function shallowRef<T = any>(): ShallowRef<T | undefined>
export function shallowRef(value?: unknown) {
return createRef(value, true)
}
}
export type ToRef<T> = [T] extends [Ref] ? T : Ref<T>
+
export function toRef<T extends object, K extends keyof T>(
object: T,
key: K
: T[K]
}
-export type UnwrapRef<T> = T extends Ref<infer V>
+export type UnwrapRef<T> = T extends ShallowRef<infer V>
+ ? V
+ : T extends Ref<infer V>
? UnwrapRefSimple<V>
: UnwrapRefSimple<T>
? T
: T extends Array<any>
? { [K in keyof T]: UnwrapRefSimple<T[K]> }
- : T extends object
+ : T extends object & { [ShallowReactiveMarker]?: never }
? {
[P in keyof T]: P extends symbol ? T[P] : UnwrapRef<T[P]>
}
testUnrefGenerics(1)
// #4732
-const baz = shallowReactive({
- foo: {
- bar: ref(42)
- }
+describe('ref in shallow reactive', () => {
+ const baz = shallowReactive({
+ foo: {
+ bar: ref(42)
+ }
+ })
+
+ const foo = toRef(baz, 'foo')
+
+ expectType<Ref<number>>(foo.value.bar)
+ expectType<number>(foo.value.bar.value)
+})
+
+// #4771
+describe('shallow reactive in reactive', () => {
+ const baz = reactive({
+ foo: shallowReactive({
+ a: {
+ b: ref(42)
+ }
+ })
+ })
+
+ const foo = toRef(baz, 'foo')
+
+ expectType<Ref<number>>(foo.value.a.b)
+ expectType<number>(foo.value.a.b.value)
})
-const foo = toRef(baz, 'foo')
+describe('shallow ref in reactive', () => {
+ const x = reactive({
+ foo: shallowRef({
+ bar: {
+ baz: ref(123),
+ qux: reactive({
+ z: ref(123)
+ })
+ }
+ })
+ })
+
+ expectType<Ref<number>>(x.foo.bar.baz)
+ expectType<number>(x.foo.bar.qux.z)
+})
+
+describe('ref in shallow ref', () => {
+ const x = shallowRef({
+ a: ref(123)
+ })
-expectType<Ref<number>>(foo.value.bar)
-expectType<number>(foo.value.bar.value)
+ expectType<Ref<number>>(x.value.a)
+})
+
+describe('reactive in shallow ref', () => {
+ const x = shallowRef({
+ a: reactive({
+ b: ref(0)
+ })
+ })
+
+ expectType<number>(x.value.a.b)
+})