55 isFunction ,
66 isIntegerKey ,
77 isObject ,
8+ isSymbol ,
89} from '@vue/shared'
910import { Dep , getDepFromReactive } from './dep'
1011import {
@@ -333,6 +334,22 @@ export type ToRefs<T = any> = {
333334 [ K in keyof T ] : ToRef < T [ K ] >
334335}
335336
337+ type ArrayStringKey < T > = T extends readonly any [ ]
338+ ? number extends T [ 'length' ]
339+ ? `${number } `
340+ : never
341+ : never
342+
343+ type ToRefKey < T > = keyof T | ArrayStringKey < T >
344+
345+ type ToRefValue < T extends object , K extends ToRefKey < T > > = K extends keyof T
346+ ? T [ K ]
347+ : T extends readonly ( infer V ) [ ]
348+ ? K extends ArrayStringKey < T >
349+ ? V
350+ : never
351+ : never
352+
336353/**
337354 * Converts a reactive object to a plain object where each property of the
338355 * 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> {
358375 public _value : T [ K ] = undefined !
359376
360377 private readonly _raw : T
378+ private readonly _key : K
361379 private readonly _shallow : boolean
362380
363381 constructor (
364382 private readonly _object : T ,
365- private readonly _key : K ,
383+ key : K ,
366384 private readonly _defaultValue ?: T [ K ] ,
367385 ) {
386+ this . _key = ( isSymbol ( key ) ? key : String ( key ) ) as K
368387 this . _raw = toRaw ( _object )
369388
370389 let shallow = true
371390 let obj = _object
372391
373392 // For an array with integer key, refs are not unwrapped
374- if ( ! isArray ( _object ) || ! isIntegerKey ( String ( _key ) ) ) {
393+ if ( ! isArray ( _object ) || isSymbol ( this . _key ) || ! isIntegerKey ( this . _key ) ) {
375394 // Otherwise, check each proxy layer for unwrapping
376395 do {
377396 shallow = ! isProxy ( obj ) || isShallow ( obj )
@@ -469,19 +488,19 @@ export function toRef<T>(
469488 : T extends Ref
470489 ? T
471490 : Ref < UnwrapRef < T > >
472- export function toRef < T extends object , K extends keyof T > (
491+ export function toRef < T extends object , K extends ToRefKey < T > > (
473492 object : T ,
474493 key : K ,
475- ) : ToRef < T [ K ] >
476- export function toRef < T extends object , K extends keyof T > (
494+ ) : ToRef < ToRefValue < T , K > >
495+ export function toRef < T extends object , K extends ToRefKey < T > > (
477496 object : T ,
478497 key : K ,
479- defaultValue : T [ K ] ,
480- ) : ToRef < Exclude < T [ K ] , undefined > >
498+ defaultValue : ToRefValue < T , K > ,
499+ ) : ToRef < Exclude < ToRefValue < T , K > , undefined > >
481500/*@__NO_SIDE_EFFECTS__ */
482501export function toRef (
483- source : Record < string , any > | MaybeRef ,
484- key ?: string ,
502+ source : Record < PropertyKey , any > | MaybeRef ,
503+ key ?: string | number | symbol ,
485504 defaultValue ?: unknown ,
486505) : Ref {
487506 if ( isRef ( source ) ) {
@@ -496,8 +515,8 @@ export function toRef(
496515}
497516
498517function propertyToRef (
499- source : Record < string , any > ,
500- key : string ,
518+ source : Record < PropertyKey , any > ,
519+ key : string | number | symbol ,
501520 defaultValue ?: unknown ,
502521) {
503522 return new ObjectRefImpl ( source , key , defaultValue ) as any
0 commit comments