Skip to content

Commit c1d6e01

Browse files
authored
feat(shared): ensure return types exists (#4659)
1 parent 4c97045 commit c1d6e01

File tree

40 files changed

+197
-83
lines changed

40 files changed

+197
-83
lines changed

packages/shared/computedEager/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
import type { ShallowRef, WatchOptionsBase } from 'vue'
55
import { readonly, shallowRef, watchEffect } from 'vue'
66

7+
export type ComputedEagerOptions = WatchOptionsBase
8+
9+
export type ComputedEagerReturn<T = any> = Readonly<ShallowRef<T>>
10+
711
/**
812
* Note: If you are using Vue 3.4+, you can straight use computed instead.
913
* Because in Vue 3.4+, if computed new value does not change,
@@ -14,7 +18,7 @@ import { readonly, shallowRef, watchEffect } from 'vue'
1418
* @param options WatchOptionsBase
1519
* @returns readonly shallowRef
1620
*/
17-
export function computedEager<T>(fn: () => T, options?: WatchOptionsBase): Readonly<ShallowRef<T>> {
21+
export function computedEager<T>(fn: () => T, options?: ComputedEagerOptions): ComputedEagerReturn<T> {
1822
const result = shallowRef()
1923

2024
watchEffect(() => {

packages/shared/computedWithControl/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ export interface ComputedWithControlRefExtra {
1212
export interface ComputedRefWithControl<T> extends ComputedRef<T>, ComputedWithControlRefExtra {}
1313
export interface WritableComputedRefWithControl<T> extends WritableComputedRef<T>, ComputedWithControlRefExtra {}
1414

15+
export type ComputedWithControlRef<T = any> = ComputedRefWithControl<T> | WritableComputedRefWithControl<T>
16+
1517
export function computedWithControl<T, S>(
1618
source: WatchSource<S> | WatchSource<S>[],
1719
fn: ComputedGetter<T>
@@ -31,7 +33,7 @@ export function computedWithControl<T, S>(
3133
export function computedWithControl<T, S>(
3234
source: WatchSource<S> | WatchSource<S>[],
3335
fn: ComputedGetter<T> | WritableComputedOptions<T>,
34-
) {
36+
): ComputedWithControlRef<T> {
3537
let v: T = undefined!
3638
let track: Fn
3739
let trigger: Fn

packages/shared/createEventHook/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,14 @@ export interface EventHook<T = any> {
2828
clear: () => void
2929
}
3030

31+
export type EventHookReturn<T> = EventHook<T>
32+
3133
/**
3234
* Utility for creating event hooks
3335
*
3436
* @see https://vueuse.org/createEventHook
3537
*/
36-
export function createEventHook<T = any>(): EventHook<T> {
38+
export function createEventHook<T = any>(): EventHookReturn<T> {
3739
const fns: Set<Callback<T>> = new Set()
3840

3941
const off = (fn: Callback<T>) => {

packages/shared/createGlobalState/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { AnyFn } from '../utils'
22
import { effectScope } from 'vue'
33

4+
export type CreateGlobalStateReturn<Fn extends AnyFn = AnyFn> = Fn
5+
46
/**
57
* Keep states in the global scope to be reusable across Vue instances.
68
*
@@ -9,7 +11,7 @@ import { effectScope } from 'vue'
911
*/
1012
export function createGlobalState<Fn extends AnyFn>(
1113
stateFactory: Fn,
12-
): Fn {
14+
): CreateGlobalStateReturn<Fn> {
1315
let initialized = false
1416
let state: any
1517
const scope = effectScope(true)

packages/shared/createRef/index.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { Ref, ShallowRef } from 'vue'
22
import { ref as deepRef, shallowRef } from 'vue'
33

4+
export type CreateRefReturn<T = any, D extends boolean = false> = ShallowOrDeepRef<T, D>
5+
46
export type ShallowOrDeepRef<T = any, D extends boolean = false> = D extends true ? Ref<T> : ShallowRef<T>
57

68
/**
@@ -16,11 +18,11 @@ export type ShallowOrDeepRef<T = any, D extends boolean = false> = D extends tru
1618
* @param deep
1719
* @returns the `deepRef` or `shallowRef`
1820
*/
19-
export function createRef<T = any, D extends boolean = false>(value: T, deep?: D): ShallowOrDeepRef<T, D> {
21+
export function createRef<T = any, D extends boolean = false>(value: T, deep?: D): CreateRefReturn<T, D> {
2022
if (deep === true) {
21-
return deepRef(value) as ShallowOrDeepRef<T, D>
23+
return deepRef(value) as CreateRefReturn<T, D>
2224
}
2325
else {
24-
return shallowRef(value) as ShallowOrDeepRef<T, D>
26+
return shallowRef(value) as CreateRefReturn<T, D>
2527
}
2628
}

packages/shared/createSharedComposable/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import type { AnyFn } from '../utils'
33
import { effectScope } from 'vue'
44
import { tryOnScopeDispose } from '../tryOnScopeDispose'
55

6+
export type SharedComposableReturn<T extends AnyFn = AnyFn> = T
7+
68
/**
79
* Make a composable function usable with multiple Vue instances.
810
*
911
* @see https://vueuse.org/createSharedComposable
1012
*/
11-
export function createSharedComposable<Fn extends AnyFn>(composable: Fn): Fn {
13+
export function createSharedComposable<Fn extends AnyFn>(composable: Fn): SharedComposableReturn<Fn> {
1214
let subscribers = 0
1315
let state: ReturnType<Fn> | undefined
1416
let scope: EffectScope | undefined

packages/shared/extendRef/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import type { Ref, ShallowUnwrapRef } from 'vue'
1+
import type { Ref, ShallowUnwrapRef, UnwrapRef } from 'vue'
22
import { isRef } from 'vue'
33

4+
export type ExtendRefReturn<T = any> = Ref<T>
5+
46
export interface ExtendRefOptions<Unwrap extends boolean = boolean> {
57
/**
68
* Is the extends properties enumerable
@@ -27,7 +29,7 @@ export function extendRef<R extends Ref<any>, Extend extends object, Options ext
2729
export function extendRef<R extends Ref<any>, Extend extends object, Options extends ExtendRefOptions>(ref: R, extend: Extend, options?: Options): Extend & R
2830

2931
// implementation
30-
export function extendRef<R extends Ref<any>, Extend extends object>(ref: R, extend: Extend, { enumerable = false, unwrap = true }: ExtendRefOptions = {}) {
32+
export function extendRef<R extends Ref<any>, Extend extends object>(ref: R, extend: Extend, { enumerable = false, unwrap = true }: ExtendRefOptions = {}): ExtendRefReturn<UnwrapRef<R>> {
3133
for (const [key, value] of Object.entries(extend)) {
3234
if (key === 'value')
3335
continue

packages/shared/get/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { unref } from 'vue'
77
*/
88
export function get<T>(ref: MaybeRef<T>): T
99
export function get<T, K extends keyof T>(ref: MaybeRef<T>, key: K): T[K]
10-
1110
export function get(obj: MaybeRef<any>, key?: string | number | symbol) {
1211
if (key == null)
1312
return unref(obj)

packages/shared/isDefined/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import type { ComputedRef, Ref } from 'vue'
33
// eslint-disable-next-line no-restricted-imports
44
import { unref } from 'vue'
55

6+
export type IsDefinedReturn = boolean
7+
68
export function isDefined<T>(v: ComputedRef<T>): v is ComputedRef<Exclude<T, null | undefined>>
79
export function isDefined<T>(v: Ref<T>): v is Ref<Exclude<T, null | undefined>>
810
export function isDefined<T>(v: T): v is Exclude<T, null | undefined>
9-
export function isDefined<T>(v: Ref<T>): boolean {
11+
export function isDefined<T>(v: Ref<T>): IsDefinedReturn {
1012
return unref(v) != null
1113
}

packages/shared/provideLocal/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import type { InjectionKey } from 'vue'
12
import { getCurrentInstance, provide } from 'vue'
23
import { localProvidedStateMap } from './map'
34

5+
export type ProvideLocalReturn = void
6+
47
/**
58
* On the basis of `provide`, it is allowed to directly call inject to obtain the value after call provide in the same component.
69
*
@@ -10,7 +13,7 @@ import { localProvidedStateMap } from './map'
1013
* const injectedValue = injectLocal('MyInjectionKey') // injectedValue === 1
1114
* ```
1215
*/
13-
export const provideLocal: typeof provide = (key, value) => {
16+
export function provideLocal<T, K = InjectionKey<T> | string | number>(key: K, value: K extends InjectionKey<infer V> ? V : T): ProvideLocalReturn {
1417
const instance = getCurrentInstance()?.proxy
1518
if (instance == null)
1619
throw new Error('provideLocal must be called in setup')
@@ -21,5 +24,5 @@ export const provideLocal: typeof provide = (key, value) => {
2124
const localProvidedState = localProvidedStateMap.get(instance)!
2225
// @ts-expect-error allow InjectionKey as key
2326
localProvidedState[key] = value
24-
provide(key, value)
27+
return provide<T, K>(key, value)
2528
}

packages/shared/reactify/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import type { ComputedRef, MaybeRef, MaybeRefOrGetter } from 'vue'
22

3+
import type { AnyFn } from '../utils'
34
// eslint-disable-next-line no-restricted-imports
45
import { computed, toValue, unref } from 'vue'
56

67
export type Reactified<T, Computed extends boolean> = T extends (...args: infer A) => infer R
78
? (...args: { [K in keyof A]: Computed extends true ? MaybeRefOrGetter<A[K]> : MaybeRef<A[K]> }) => ComputedRef<R>
89
: never
910

11+
export type ReactifyReturn<T extends AnyFn = AnyFn, K extends boolean = true> = Reactified<T, K>
12+
1013
export interface ReactifyOptions<T extends boolean> {
1114
/**
1215
* Accept passing a function as a reactive getter
@@ -22,8 +25,9 @@ export interface ReactifyOptions<T extends boolean> {
2225
* and returns a ComputedRef, with proper typing.
2326
*
2427
* @param fn - Source function
28+
* @param options - Options
2529
*/
26-
export function reactify<T extends Function, K extends boolean = true>(fn: T, options?: ReactifyOptions<K>): Reactified<T, K> {
30+
export function reactify<T extends AnyFn, K extends boolean = true>(fn: T, options?: ReactifyOptions<K>): ReactifyReturn<T, K> {
2731
const unrefFn = options?.computedGetter === false ? unref : toValue
2832
return function (this: any, ...args: any[]) {
2933
return computed(() => fn.apply(this, args.map(i => unrefFn(i))))

packages/shared/reactifyObject/index.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { reactify } from '../reactify'
44

55
export type ReactifyNested<T, Keys extends keyof T = keyof T, S extends boolean = true> = { [K in Keys]: T[K] extends AnyFn ? Reactified<T[K], S> : T[K] }
66

7+
export type ReactifyObjectReturn<T, Keys extends keyof T, S extends boolean = true> = ReactifyNested<T, Keys, S>
8+
79
export interface ReactifyObjectOptions<T extends boolean> extends ReactifyOptions<T> {
810
/**
911
* Includes names from Object.getOwnPropertyNames
@@ -16,10 +18,10 @@ export interface ReactifyObjectOptions<T extends boolean> extends ReactifyOption
1618
/**
1719
* Apply `reactify` to an object
1820
*/
19-
export function reactifyObject<T extends object, Keys extends keyof T>(obj: T, keys?: (keyof T)[]): ReactifyNested<T, Keys, true>
20-
export function reactifyObject<T extends object, S extends boolean = true>(obj: T, options?: ReactifyObjectOptions<S>): ReactifyNested<T, keyof T, S>
21+
export function reactifyObject<T extends object, Keys extends keyof T>(obj: T, keys?: (keyof T)[]): ReactifyObjectReturn<T, Keys, true>
22+
export function reactifyObject<T extends object, S extends boolean = true>(obj: T, options?: ReactifyObjectOptions<S>): ReactifyObjectReturn<T, keyof T, S>
2123

22-
export function reactifyObject<T extends object, S extends boolean = true>(obj: T, optionsOrKeys: ReactifyObjectOptions<S> | (keyof T)[] = {}): ReactifyNested<T, keyof T, S> {
24+
export function reactifyObject<T extends object, S extends boolean = true>(obj: T, optionsOrKeys: ReactifyObjectOptions<S> | (keyof T)[] = {}): ReactifyObjectReturn<T, keyof T, S> {
2325
let keys: string[] = []
2426
let options: ReactifyOptions<S> | undefined
2527
if (Array.isArray(optionsOrKeys)) {

packages/shared/reactiveComputed/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ import type { ComputedGetter, UnwrapNestedRefs } from 'vue'
22
import { computed } from 'vue'
33
import { toReactive } from '../toReactive'
44

5+
export type ReactiveComputedReturn<T extends object> = UnwrapNestedRefs<T>
6+
57
/**
68
* Computed reactive object.
79
*/
8-
export function reactiveComputed<T extends object>(fn: ComputedGetter<T>): UnwrapNestedRefs<T> {
9-
return toReactive(computed(fn))
10+
export function reactiveComputed<T extends object>(fn: ComputedGetter<T>): ReactiveComputedReturn<T> {
11+
return toReactive<T>(computed<T>(fn))
1012
}

packages/shared/reactiveOmit/index.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
import { toRefs, toValue } from 'vue'
22
import { reactiveComputed } from '../reactiveComputed'
33

4+
export type ReactiveOmitReturn<T extends object, K extends keyof T | undefined = undefined> =
5+
[K] extends [undefined]
6+
? Partial<T>
7+
: Omit<T, Extract<K, keyof T>>
8+
49
export type ReactiveOmitPredicate<T> = (value: T[keyof T], key: keyof T) => boolean
510

611
export function reactiveOmit<T extends object, K extends keyof T>(
712
obj: T,
813
...keys: (K | K[])[]
9-
): Omit<T, K>
14+
): ReactiveOmitReturn<T, K>
1015
export function reactiveOmit<T extends object>(
1116
obj: T,
1217
predicate: ReactiveOmitPredicate<T>,
13-
): Partial<T>
18+
): ReactiveOmitReturn<T>
1419
/**
1520
* Reactively omit fields from a reactive object
1621
*
@@ -19,7 +24,7 @@ export function reactiveOmit<T extends object>(
1924
export function reactiveOmit<T extends object, K extends keyof T>(
2025
obj: T,
2126
...keys: (K | K[])[]
22-
): Omit<T, K> {
27+
): ReactiveOmitReturn<T, K> {
2328
const flatKeys = keys.flat() as K[]
2429
const predicate = flatKeys[0] as unknown as ReactiveOmitPredicate<T>
2530
return reactiveComputed<any>(() =>

packages/shared/reactivePick/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@ import { toRefs, toValue } from 'vue'
33
import { reactiveComputed } from '../reactiveComputed'
44
import { toRef } from '../toRef'
55

6+
export type ReactivePickReturn<T extends object, K extends keyof T> = { [S in K]: UnwrapRef<T[S]> }
7+
68
export type ReactivePickPredicate<T> = (value: T[keyof T], key: keyof T) => boolean
79

810
export function reactivePick<T extends object, K extends keyof T>(
911
obj: T,
1012
...keys: (K | K[])[]
11-
): { [S in K]: UnwrapRef<T[S]> }
13+
): ReactivePickReturn<T, K>
1214
export function reactivePick<T extends object>(
1315
obj: T,
1416
predicate: ReactivePickPredicate<T>
15-
): { [S in keyof T]?: UnwrapRef<T[S]> }
17+
): ReactivePickReturn<T, keyof T>
1618

1719
/**
1820
* Reactively pick fields from a reactive object

packages/shared/refAutoReset/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import type { MaybeRefOrGetter, Ref } from 'vue'
22
import { customRef, toValue } from 'vue'
33
import { tryOnScopeDispose } from '../tryOnScopeDispose'
44

5+
export type RefAutoResetReturn<T = any> = Ref<T>
6+
57
/**
68
* Create a ref which will be reset to the default value after some time.
79
*
810
* @see https://vueuse.org/refAutoReset
911
* @param defaultValue The value which will be set.
1012
* @param afterMs A zero-or-greater delay in milliseconds.
1113
*/
12-
export function refAutoReset<T>(defaultValue: MaybeRefOrGetter<T>, afterMs: MaybeRefOrGetter<number> = 10000): Ref<T> {
14+
export function refAutoReset<T>(defaultValue: MaybeRefOrGetter<T>, afterMs: MaybeRefOrGetter<number> = 10000): RefAutoResetReturn<T> {
1315
return customRef<T>((track, trigger) => {
1416
let value: T = toValue(defaultValue)
1517
let timer: any

packages/shared/refDebounced/index.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
import type { MaybeRefOrGetter, Ref } from 'vue'
22
import type { DebounceFilterOptions } from '../utils'
3-
import { ref as deepRef, watch } from 'vue'
3+
import { ref as deepRef, shallowReadonly, toValue, watch } from 'vue'
44
import { useDebounceFn } from '../useDebounceFn'
55

6+
export type RefDebouncedReturn<T = any> = Readonly<Ref<T>>
7+
68
/**
79
* Debounce updates of a ref.
810
*
911
* @return A new debounced ref.
1012
*/
11-
export function refDebounced<T>(value: Ref<T>, ms: MaybeRefOrGetter<number> = 200, options: DebounceFilterOptions = {}): Readonly<Ref<T>> {
12-
const debounced = deepRef(value.value as T) as Ref<T>
13+
export function refDebounced<T>(value: Ref<T>, ms: MaybeRefOrGetter<number> = 200, options: DebounceFilterOptions = {}): RefDebouncedReturn<T> {
14+
const debounced = deepRef(toValue(value)) as Ref<T>
1315

1416
const updater = useDebounceFn(() => {
1517
debounced.value = value.value
1618
}, ms, options)
1719

1820
watch(value, () => updater())
1921

20-
return debounced
22+
return shallowReadonly(debounced)
2123
}
2224

2325
// alias

packages/shared/refThrottled/index.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
11
import type { Ref } from 'vue'
2-
import { ref as deepRef, watch } from 'vue'
2+
import { ref as deepRef, toValue, watch } from 'vue'
33
import { useThrottleFn } from '../useThrottleFn'
44

5+
export type RefThrottledReturn<T = any> = Ref<T>
6+
57
/**
68
* Throttle execution of a function. Especially useful for rate limiting
79
* execution of handlers on events like resize and scroll.
810
*
911
* @param value Ref value to be watched with throttle effect
1012
* @param delay A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful.
11-
* @param [trailing] if true, update the value again after the delay time is up
12-
* @param [leading] if true, update the value on the leading edge of the ms timeout
13+
* @param trailing if true, update the value again after the delay time is up
14+
* @param leading if true, update the value on the leading edge of the ms timeout
1315
*/
14-
export function refThrottled<T>(value: Ref<T>, delay = 200, trailing = true, leading = true) {
16+
export function refThrottled<T = any>(value: Ref<T>, delay = 200, trailing = true, leading = true): RefThrottledReturn<T> {
1517
if (delay <= 0)
1618
return value
1719

18-
const throttled: Ref<T> = deepRef(value.value as T) as Ref<T>
20+
const throttled = deepRef(toValue(value))
1921

2022
const updater = useThrottleFn(() => {
2123
throttled.value = value.value
2224
}, delay, trailing, leading)
2325

2426
watch(value, () => updater())
2527

26-
return throttled
28+
return throttled as Ref<T>
2729
}
2830

2931
// alias

packages/shared/toRefs/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface ToRefsOptions {
1515
*
1616
* @see https://vueuse.org/toRefs
1717
* @param objectRef A ref or normal object or array.
18+
* @param options Options
1819
*/
1920
export function toRefs<T extends object>(
2021
objectRef: MaybeRef<T>,

0 commit comments

Comments
 (0)