Skip to content

Commit fe62b52

Browse files
zry656565Brooooooklyn
authored andcommitted
fix(#15): improve typing of useObservable
1 parent 8731be7 commit fe62b52

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

src/use-observable.ts

+27-15
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
11
import { Observable, BehaviorSubject } from 'rxjs'
22
import { useState, useEffect, useMemo } from 'react'
33

4-
export type InputFactory<T, U = undefined> = U extends undefined
5-
? (state$: Observable<T>) => Observable<T>
6-
: (inputs$: Observable<U>, state$: Observable<T>) => Observable<T>
4+
export type InputFactory<State, Inputs = undefined> = Inputs extends undefined
5+
? (state$: Observable<State>) => Observable<State>
6+
: (inputs$: Observable<RestrictArray<Inputs>>, state$: Observable<State>) => Observable<State>
77

8-
export function useObservable<T>(inputFactory: InputFactory<T>): T | null
9-
export function useObservable<T>(inputFactory: InputFactory<T>, initialState: T): T
10-
export function useObservable<T, U>(inputFactory: InputFactory<T, U>, initialState: T, inputs: U): T
8+
export type RestrictArray<T> = T extends any[] ? T : []
119

12-
export function useObservable<T, U>(inputFactory: InputFactory<T, U>, initialState?: T, inputs?: U): T | null {
10+
export function useObservable<State>(inputFactory: InputFactory<State>): State | null
11+
export function useObservable<State>(inputFactory: InputFactory<State>, initialState: State): State
12+
export function useObservable<State, Inputs>(
13+
inputFactory: InputFactory<State, Inputs>,
14+
initialState: State,
15+
inputs: RestrictArray<Inputs>,
16+
): State
17+
18+
export function useObservable<State, Inputs extends ReadonlyArray<any>>(
19+
inputFactory: InputFactory<State, Inputs>,
20+
initialState?: State,
21+
inputs?: RestrictArray<Inputs>,
22+
): State | null {
1323
const [state, setState] = useState(typeof initialState !== 'undefined' ? initialState : null)
1424

1525
const { state$, inputs$ } = useMemo(() => {
16-
const stateSubject$ = new BehaviorSubject<T | undefined>(initialState)
17-
const inputSubject$ = new BehaviorSubject<U | undefined>(inputs)
26+
const stateSubject$ = new BehaviorSubject<State | undefined>(initialState)
27+
const inputSubject$ = new BehaviorSubject<RestrictArray<Inputs> | undefined>(inputs)
1828

1929
return {
2030
state$: stateSubject$,
@@ -24,18 +34,20 @@ export function useObservable<T, U>(inputFactory: InputFactory<T, U>, initialSta
2434

2535
useMemo(() => {
2636
inputs$.next(inputs)
27-
}, ((inputs as unknown) as ReadonlyArray<any>) || [])
37+
}, inputs || [])
2838

2939
useEffect(
3040
() => {
31-
let output$: BehaviorSubject<T>
41+
let output$: BehaviorSubject<State>
3242
if (inputs) {
3343
output$ = (inputFactory as (
34-
inputs$: Observable<U | undefined>,
35-
state$: Observable<T | undefined>,
36-
) => Observable<T>)(inputs$, state$) as BehaviorSubject<T>
44+
inputs$: Observable<RestrictArray<Inputs> | undefined>,
45+
state$: Observable<State | undefined>,
46+
) => Observable<State>)(inputs$, state$) as BehaviorSubject<State>
3747
} else {
38-
output$ = (inputFactory as (state$: Observable<T | undefined>) => Observable<T>)(state$) as BehaviorSubject<T>
48+
output$ = (inputFactory as (state$: Observable<State | undefined>) => Observable<State>)(
49+
state$,
50+
) as BehaviorSubject<State>
3951
}
4052
const subscription = output$.subscribe((value) => {
4153
state$.next(value)

0 commit comments

Comments
 (0)