From 25f8eec4484f5ffdf85fb45cf65d5fa7d96fcf57 Mon Sep 17 00:00:00 2001 From: crimx Date: Fri, 15 Oct 2021 18:10:56 +0800 Subject: [PATCH] feat(observable-hooks): better type infer for BehaviorSubject --- .../__tests__/use-observable-state.spec.ts | 16 +++++++++++++- .../src/use-observable-state.ts | 21 +++++++------------ 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/packages/observable-hooks/__tests__/use-observable-state.spec.ts b/packages/observable-hooks/__tests__/use-observable-state.spec.ts index d5bf672f..c0516f98 100644 --- a/packages/observable-hooks/__tests__/use-observable-state.spec.ts +++ b/packages/observable-hooks/__tests__/use-observable-state.spec.ts @@ -1,6 +1,6 @@ import { useObservableState, identity } from '../src' import { renderHook, act } from '@testing-library/react-hooks' -import { of, Subject, throwError } from 'rxjs' +import { BehaviorSubject, of, Subject, throwError } from 'rxjs' import { map, scan } from 'rxjs/operators' describe('useObservableState', () => { @@ -51,6 +51,20 @@ describe('useObservableState', () => { expect(result.current[0]).toBe(1) }) + it('should get the init state of BehaviorSubject without initialState', () => { + const value$ = new BehaviorSubject('22') + const { result } = renderHook(() => useObservableState(value$)) + expect(result.current).toBe('22') + }) + + it('should ignore the manual initialState for BehaviorSubject', () => { + const value$ = new BehaviorSubject('22') + const { result } = renderHook(() => + useObservableState(value$, 'initialState') + ) + expect(result.current).toBe('22') + }) + it('should ignore the given init state when Observable also emits sync values', () => { const { result } = renderHook(() => useObservableState(() => of(1, 2), 3)) expect(result.current[0]).toBe(2) diff --git a/packages/observable-hooks/src/use-observable-state.ts b/packages/observable-hooks/src/use-observable-state.ts index a8ebe151..f474bc87 100644 --- a/packages/observable-hooks/src/use-observable-state.ts +++ b/packages/observable-hooks/src/use-observable-state.ts @@ -41,22 +41,19 @@ import { useRefFn, getEmptySubject } from './helpers' * * @template TState Output state. * - * @param input$ An Observable. + * @param input$ A BehaviorSubject. */ export function useObservableState( - input$: Observable -): TState | undefined + input$: BehaviorSubject +): TState /** * @template TState Output state. * - * @param input$ A BehaviorSubject. - * @param initialState Optional initial state (defaults to the BehaviorSubject's value). - * Can be the state value or a function that returns the state. + * @param input$ An Observable. */ export function useObservableState( - input$: BehaviorSubject, - initialState?: TState | (() => TState) -): TState + input$: Observable +): TState | undefined /** * @template TState Output state. * @@ -105,11 +102,7 @@ export function useObservableState( ) => Observable), initialState?: TState | (() => TState) ): TState | undefined | [TState | undefined, (input: TInput) => void] { - const [state, setState] = useState( - state$OrInit instanceof BehaviorSubject - ? state$OrInit.value - : initialState - ) + const [state, setState] = useState(initialState) let callback: undefined | ((input: TInput) => void) let state$: Observable