diff --git a/src/use-observable.ts b/src/use-observable.ts index 9d32d25a..19d43c5f 100644 --- a/src/use-observable.ts +++ b/src/use-observable.ts @@ -1,20 +1,30 @@ import { Observable, BehaviorSubject } from 'rxjs' import { useState, useEffect, useMemo } from 'react' -export type InputFactory = U extends undefined - ? (state$: Observable) => Observable - : (inputs$: Observable, state$: Observable) => Observable +export type InputFactory = Inputs extends undefined + ? (state$: Observable) => Observable + : (inputs$: Observable>, state$: Observable) => Observable -export function useObservable(inputFactory: InputFactory): T | null -export function useObservable(inputFactory: InputFactory, initialState: T): T -export function useObservable(inputFactory: InputFactory, initialState: T, inputs: U): T +export type RestrictArray = T extends any[] ? T : [] -export function useObservable(inputFactory: InputFactory, initialState?: T, inputs?: U): T | null { +export function useObservable(inputFactory: InputFactory): State | null +export function useObservable(inputFactory: InputFactory, initialState: State): State +export function useObservable( + inputFactory: InputFactory, + initialState: State, + inputs: RestrictArray, +): State + +export function useObservable>( + inputFactory: InputFactory, + initialState?: State, + inputs?: RestrictArray, +): State | null { const [state, setState] = useState(typeof initialState !== 'undefined' ? initialState : null) const { state$, inputs$ } = useMemo(() => { - const stateSubject$ = new BehaviorSubject(initialState) - const inputSubject$ = new BehaviorSubject(inputs) + const stateSubject$ = new BehaviorSubject(initialState) + const inputSubject$ = new BehaviorSubject | undefined>(inputs) return { state$: stateSubject$, @@ -24,18 +34,20 @@ export function useObservable(inputFactory: InputFactory, initialSta useMemo(() => { inputs$.next(inputs) - }, ((inputs as unknown) as ReadonlyArray) || []) + }, inputs || []) useEffect( () => { - let output$: BehaviorSubject + let output$: BehaviorSubject if (inputs) { output$ = (inputFactory as ( - inputs$: Observable, - state$: Observable, - ) => Observable)(inputs$, state$) as BehaviorSubject + inputs$: Observable | undefined>, + state$: Observable, + ) => Observable)(inputs$, state$) as BehaviorSubject } else { - output$ = (inputFactory as (state$: Observable) => Observable)(state$) as BehaviorSubject + output$ = (inputFactory as (state$: Observable) => Observable)( + state$, + ) as BehaviorSubject } const subscription = output$.subscribe((value) => { state$.next(value)