Skip to content

Commit 1ab4f5d

Browse files
committed
fix(#15): improve typing of useObservable
1 parent 8731be7 commit 1ab4f5d

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

src/use-observable.ts

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
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 extends ReadonlyArray<any> | undefined = undefined> = Inputs extends undefined
5+
? (state$: Observable<State>) => Observable<State>
6+
: (inputs$: Observable<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 function useObservable<State>(inputFactory: InputFactory<State>): State | null
9+
export function useObservable<State>(inputFactory: InputFactory<State>, initialState: State): State
10+
export function useObservable<State, Inputs extends ReadonlyArray<any>>(
11+
inputFactory: InputFactory<State, Inputs>,
12+
initialState: State,
13+
inputs: Inputs,
14+
): State
1115

12-
export function useObservable<T, U>(inputFactory: InputFactory<T, U>, initialState?: T, inputs?: U): T | null {
16+
export function useObservable<State, Inputs extends ReadonlyArray<any>>(
17+
inputFactory: InputFactory<State, Inputs>,
18+
initialState?: State,
19+
inputs?: Inputs,
20+
): State | null {
1321
const [state, setState] = useState(typeof initialState !== 'undefined' ? initialState : null)
1422

1523
const { state$, inputs$ } = useMemo(() => {
16-
const stateSubject$ = new BehaviorSubject<T | undefined>(initialState)
17-
const inputSubject$ = new BehaviorSubject<U | undefined>(inputs)
24+
const stateSubject$ = new BehaviorSubject<State | undefined>(initialState)
25+
const inputSubject$ = new BehaviorSubject<Inputs | undefined>(inputs)
1826

1927
return {
2028
state$: stateSubject$,
@@ -24,18 +32,20 @@ export function useObservable<T, U>(inputFactory: InputFactory<T, U>, initialSta
2432

2533
useMemo(() => {
2634
inputs$.next(inputs)
27-
}, ((inputs as unknown) as ReadonlyArray<any>) || [])
35+
}, inputs || [])
2836

2937
useEffect(
3038
() => {
31-
let output$: BehaviorSubject<T>
39+
let output$: BehaviorSubject<State>
3240
if (inputs) {
3341
output$ = (inputFactory as (
34-
inputs$: Observable<U | undefined>,
35-
state$: Observable<T | undefined>,
36-
) => Observable<T>)(inputs$, state$) as BehaviorSubject<T>
42+
inputs$: Observable<Inputs | undefined>,
43+
state$: Observable<State | undefined>,
44+
) => Observable<State>)(inputs$, state$) as BehaviorSubject<State>
3745
} else {
38-
output$ = (inputFactory as (state$: Observable<T | undefined>) => Observable<T>)(state$) as BehaviorSubject<T>
46+
output$ = (inputFactory as (state$: Observable<State | undefined>) => Observable<State>)(
47+
state$,
48+
) as BehaviorSubject<State>
3949
}
4050
const subscription = output$.subscribe((value) => {
4151
state$.next(value)

0 commit comments

Comments
 (0)