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) |     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', () => { |   test('toRefs', () => { | ||||||
|     const a = reactive({ |     const a = reactive({ | ||||||
|       x: 1, |       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> { | class ObjectRefImpl<T extends object, K extends keyof T> { | ||||||
|   public readonly __v_isRef = true |   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() { |   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) { |   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>( | export function toRef<T extends object, K extends keyof T>( | ||||||
|   object: T, |   object: T, | ||||||
|   key: K |   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]> { | ): ToRef<T[K]> { | ||||||
|   const val = object[key] |   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
 | // corner case when use narrows type
 | ||||||
|  | |||||||
| @ -224,6 +224,13 @@ expectType<Ref<string>>(p2.obj.k) | |||||||
|   expectType<Ref<number>>(toRefsResult.a.value.b) |   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
 | // #2687
 | ||||||
| interface AppData { | interface AppData { | ||||||
|   state: 'state1' | 'state2' | 'state3' |   state: 'state1' | 'state2' | 'state3' | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user