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,
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) {
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
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'