Skip to content

Commit

Permalink
feat(reactivity): enhance type inference for context-sensitive inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
jh-leong committed Nov 5, 2023
1 parent 32bdc5d commit 146fb1c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
31 changes: 30 additions & 1 deletion packages/dts-test/reactivity.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import { ref, readonly, shallowReadonly, Ref, reactive, markRaw } from 'vue'
import {
ref,
readonly,
shallowReadonly,
Ref,
reactive,
markRaw,
ComputedRef,
computed
} from 'vue'
import { describe, expectType } from './utils'

describe('should support DeepReadonly', () => {
Expand Down Expand Up @@ -62,3 +71,23 @@ describe('should unwrap tuple correctly', () => {
const reactiveTuple = reactive(tuple)
expectType<Ref<number>>(reactiveTuple[0])
})

// #1930
describe('should unwrap the computed type', () => {
interface Bar {
a: number
b: (_: any) => void
}

const computedA: ComputedRef<number> = computed(() => 1)

expectType<{ a: number }>(reactive({ a: computedA }))

expectType<Bar>(
reactive({
a: computedA, // issue happens here, but is should be okay
// @ts-expect-error
b: _ => {} // error depending on --noImplicitAny
})
)
})
5 changes: 5 additions & 0 deletions packages/reactivity/src/reactive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ function getTargetType(value: Target) {
// only unwrap nested ref
export type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRefSimple<T>

type NoInfer<T> = [T][T extends any ? 0 : never]

/**
* Returns a reactive proxy of the object.
*
Expand All @@ -80,6 +82,9 @@ export type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRefSimple<T>
* @see {@link https://vuejs.org/api/reactivity-core.html#reactive}
*/
export function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
export function reactive<T extends object>(
target: T
): NoInfer<UnwrapNestedRefs<T>>
export function reactive(target: object) {
// if trying to observe a readonly proxy, return the readonly version.
if (isReadonly(target)) {
Expand Down

0 comments on commit 146fb1c

Please sign in to comment.