Skip to content

Commit

Permalink
fix (types): do not unwrap refs in toRefs (#4966)
Browse files Browse the repository at this point in the history
  • Loading branch information
JensDll authored Nov 25, 2021
1 parent f2d2d7b commit c6cd6a7
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 38 deletions.
4 changes: 1 addition & 3 deletions packages/reactivity/src/ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,7 @@ export function customRef<T>(factory: CustomRefFactory<T>): Ref<T> {
}

export type ToRefs<T = any> = {
// #2687: somehow using ToRef<T[K]> here turns the resulting type into
// a union of multiple Ref<*> types instead of a single Ref<* | *> type.
[K in keyof T]: T[K] extends Ref ? T[K] : Ref<UnwrapRef<T[K]>>
[K in keyof T]: ToRef<T[K]>
}
export function toRefs<T extends object>(object: T): ToRefs<T> {
if (__DEV__ && !isProxy(object)) {
Expand Down
72 changes: 37 additions & 35 deletions test-dts/ref.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import {
toRef,
toRefs,
ToRefs,
shallowReactive,
watch
shallowReactive
} from './index'

function plainType(arg: number | Ref<number>) {
Expand Down Expand Up @@ -185,28 +184,45 @@ const p2 = proxyRefs(r2)
expectType<number>(p2.a)
expectType<Ref<string>>(p2.obj.k)

// toRef
const obj = {
a: 1,
b: ref(1)
}
expectType<Ref<number>>(toRef(obj, 'a'))
expectType<Ref<number>>(toRef(obj, 'b'))
// toRef and toRefs
{
const obj: {
a: number
b: Ref<number>
c: number | string
} = {
a: 1,
b: ref(1),
c: 1
}

const objWithUnionProp: { a: string | number } = {
a: 1
}
// toRef
expectType<Ref<number>>(toRef(obj, 'a'))
expectType<Ref<number>>(toRef(obj, 'b'))
// Should not distribute Refs over union
expectType<Ref<number | string>>(toRef(obj, 'c'))

// toRefs
expectType<{
a: Ref<number>
b: Ref<number>
// Should not distribute Refs over union
c: Ref<number | string>
}>(toRefs(obj))

// Both should not do any unwrapping
const someReactive = shallowReactive({
a: {
b: ref(42)
}
})

watch(toRef(objWithUnionProp, 'a'), value => {
expectType<string | number>(value)
})
const toRefResult = toRef(someReactive, 'a')
const toRefsResult = toRefs(someReactive)

// toRefs
const objRefs = toRefs(obj)
expectType<{
a: Ref<number>
b: Ref<number>
}>(objRefs)
expectType<Ref<number>>(toRefResult.value.b)
expectType<Ref<number>>(toRefsResult.a.value.b)
}

// #2687
interface AppData {
Expand Down Expand Up @@ -238,20 +254,6 @@ function testUnrefGenerics<T>(p: T | Ref<T>) {

testUnrefGenerics(1)

// #4732
describe('ref in shallow reactive', () => {
const baz = shallowReactive({
foo: {
bar: ref(42)
}
})

const foo = toRef(baz, 'foo')

expectType<Ref<number>>(foo.value.bar)
expectType<number>(foo.value.bar.value)
})

// #4771
describe('shallow reactive in reactive', () => {
const baz = reactive({
Expand Down

0 comments on commit c6cd6a7

Please sign in to comment.