|
|
@@ -5,6 +5,7 @@ import {
|
|
|
isFunction,
|
|
|
isIntegerKey,
|
|
|
isObject,
|
|
|
+ isSymbol,
|
|
|
} from '@vue/shared'
|
|
|
import { Dep, getDepFromReactive } from './dep'
|
|
|
import {
|
|
|
@@ -333,6 +334,22 @@ export type ToRefs<T = any> = {
|
|
|
[K in keyof T]: ToRef<T[K]>
|
|
|
}
|
|
|
|
|
|
+type ArrayStringKey<T> = T extends readonly any[]
|
|
|
+ ? number extends T['length']
|
|
|
+ ? `${number}`
|
|
|
+ : never
|
|
|
+ : never
|
|
|
+
|
|
|
+type ToRefKey<T> = keyof T | ArrayStringKey<T>
|
|
|
+
|
|
|
+type ToRefValue<T extends object, K extends ToRefKey<T>> = K extends keyof T
|
|
|
+ ? T[K]
|
|
|
+ : T extends readonly (infer V)[]
|
|
|
+ ? K extends ArrayStringKey<T>
|
|
|
+ ? V
|
|
|
+ : never
|
|
|
+ : never
|
|
|
+
|
|
|
/**
|
|
|
* Converts a reactive object to a plain object where each property of the
|
|
|
* resulting object is a ref pointing to the corresponding property of the
|
|
|
@@ -358,20 +375,22 @@ class ObjectRefImpl<T extends object, K extends keyof T> {
|
|
|
public _value: T[K] = undefined!
|
|
|
|
|
|
private readonly _raw: T
|
|
|
+ private readonly _key: K
|
|
|
private readonly _shallow: boolean
|
|
|
|
|
|
constructor(
|
|
|
private readonly _object: T,
|
|
|
- private readonly _key: K,
|
|
|
+ key: K,
|
|
|
private readonly _defaultValue?: T[K],
|
|
|
) {
|
|
|
+ this._key = (isSymbol(key) ? key : String(key)) as K
|
|
|
this._raw = toRaw(_object)
|
|
|
|
|
|
let shallow = true
|
|
|
let obj = _object
|
|
|
|
|
|
// For an array with integer key, refs are not unwrapped
|
|
|
- if (!isArray(_object) || !isIntegerKey(String(_key))) {
|
|
|
+ if (!isArray(_object) || isSymbol(this._key) || !isIntegerKey(this._key)) {
|
|
|
// Otherwise, check each proxy layer for unwrapping
|
|
|
do {
|
|
|
shallow = !isProxy(obj) || isShallow(obj)
|
|
|
@@ -469,19 +488,19 @@ export function toRef<T>(
|
|
|
: T extends Ref
|
|
|
? T
|
|
|
: Ref<UnwrapRef<T>>
|
|
|
-export function toRef<T extends object, K extends keyof T>(
|
|
|
+export function toRef<T extends object, K extends ToRefKey<T>>(
|
|
|
object: T,
|
|
|
key: K,
|
|
|
-): ToRef<T[K]>
|
|
|
-export function toRef<T extends object, K extends keyof T>(
|
|
|
+): ToRef<ToRefValue<T, K>>
|
|
|
+export function toRef<T extends object, K extends ToRefKey<T>>(
|
|
|
object: T,
|
|
|
key: K,
|
|
|
- defaultValue: T[K],
|
|
|
-): ToRef<Exclude<T[K], undefined>>
|
|
|
+ defaultValue: ToRefValue<T, K>,
|
|
|
+): ToRef<Exclude<ToRefValue<T, K>, undefined>>
|
|
|
/*@__NO_SIDE_EFFECTS__*/
|
|
|
export function toRef(
|
|
|
- source: Record<string, any> | MaybeRef,
|
|
|
- key?: string,
|
|
|
+ source: Record<PropertyKey, any> | MaybeRef,
|
|
|
+ key?: string | number | symbol,
|
|
|
defaultValue?: unknown,
|
|
|
): Ref {
|
|
|
if (isRef(source)) {
|
|
|
@@ -496,8 +515,8 @@ export function toRef(
|
|
|
}
|
|
|
|
|
|
function propertyToRef(
|
|
|
- source: Record<string, any>,
|
|
|
- key: string,
|
|
|
+ source: Record<PropertyKey, any>,
|
|
|
+ key: string | number | symbol,
|
|
|
defaultValue?: unknown,
|
|
|
) {
|
|
|
return new ObjectRefImpl(source, key, defaultValue) as any
|