feat(reactivity): support default value in toRef()
This commit is contained in:
		
							parent
							
								
									d0ea900922
								
							
						
					
					
						commit
						2db9c909c2
					
				| @ -269,6 +269,18 @@ describe('reactivity/ref', () => { | ||||
|     expect(toRef(r, 'x')).toBe(r.x) | ||||
|   }) | ||||
| 
 | ||||
|   test('toRef default value', () => { | ||||
|     const a: { x: number | undefined } = { x: undefined } | ||||
|     const x = toRef(a, 'x', 1) | ||||
|     expect(x.value).toBe(1) | ||||
| 
 | ||||
|     a.x = 2 | ||||
|     expect(x.value).toBe(2) | ||||
| 
 | ||||
|     a.x = undefined | ||||
|     expect(x.value).toBe(1) | ||||
|   }) | ||||
| 
 | ||||
|   test('toRefs', () => { | ||||
|     const a = reactive({ | ||||
|       x: 1, | ||||
|  | ||||
| @ -206,10 +206,15 @@ export function toRefs<T extends object>(object: T): ToRefs<T> { | ||||
| class ObjectRefImpl<T extends object, K extends keyof T> { | ||||
|   public readonly __v_isRef = true | ||||
| 
 | ||||
|   constructor(private readonly _object: T, private readonly _key: K) {} | ||||
|   constructor( | ||||
|     private readonly _object: T, | ||||
|     private readonly _key: K, | ||||
|     private readonly _defaultValue?: T[K] | ||||
|   ) {} | ||||
| 
 | ||||
|   get value() { | ||||
|     return this._object[this._key] | ||||
|     const val = this._object[this._key] | ||||
|     return val === undefined ? (this._defaultValue as T[K]) : val | ||||
|   } | ||||
| 
 | ||||
|   set value(newVal) { | ||||
| @ -222,9 +227,23 @@ export type ToRef<T> = [T] extends [Ref] ? T : Ref<T> | ||||
| export function toRef<T extends object, K extends keyof T>( | ||||
|   object: T, | ||||
|   key: K | ||||
| ): ToRef<T[K]> | ||||
| 
 | ||||
| export function toRef<T extends object, K extends keyof T>( | ||||
|   object: T, | ||||
|   key: K, | ||||
|   defaultValue: T[K] | ||||
| ): ToRef<Exclude<T[K], undefined>> | ||||
| 
 | ||||
| export function toRef<T extends object, K extends keyof T>( | ||||
|   object: T, | ||||
|   key: K, | ||||
|   defaultValue?: T[K] | ||||
| ): ToRef<T[K]> { | ||||
|   const val = object[key] | ||||
|   return isRef(val) ? val : (new ObjectRefImpl(object, key) as any) | ||||
|   return isRef(val) | ||||
|     ? val | ||||
|     : (new ObjectRefImpl(object, key, defaultValue) as any) | ||||
| } | ||||
| 
 | ||||
| // corner case when use narrows type
 | ||||
|  | ||||
| @ -224,6 +224,13 @@ expectType<Ref<string>>(p2.obj.k) | ||||
|   expectType<Ref<number>>(toRefsResult.a.value.b) | ||||
| } | ||||
| 
 | ||||
| // toRef default value
 | ||||
| { | ||||
|   const obj: { x?: number } = {} | ||||
|   const x = toRef(obj, 'x', 1) | ||||
|   expectType<Ref<number>>(x) | ||||
| } | ||||
| 
 | ||||
| // #2687
 | ||||
| interface AppData { | ||||
|   state: 'state1' | 'state2' | 'state3' | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user