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…
Reference in New Issue
Block a user