Skip to content

Commit 8624fe5

Browse files
committed
fix(typing): fix typing of useEventCallback
1 parent f3b2bb9 commit 8624fe5

File tree

3 files changed

+47
-38
lines changed

3 files changed

+47
-38
lines changed

src/type.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export type RestrictArray<T> = T extends any[] ? T : []
2+
export type VoidAsNull<T> = T extends void ? null : T

src/use-event-callback.ts

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,48 @@
1-
import { useEffect, useMemo, useState, SyntheticEvent } from 'react'
1+
import { useEffect, useMemo, useState } from 'react'
22
import { Observable, BehaviorSubject, Subject, noop } from 'rxjs'
33

4-
export type VoidAsNull<T> = T extends void ? null : T
4+
import { RestrictArray, VoidAsNull } from './type'
55

6-
export type EventCallbackState<_T, E, U, I = void> = [
7-
(e: E) => void,
8-
[U extends void ? null : U, BehaviorSubject<U | null>, BehaviorSubject<I | null>]
6+
export type EventCallbackState<EventValue, State, Inputs = void> = [
7+
(val: EventValue) => void,
8+
[State extends void ? null : State, BehaviorSubject<State | null>, BehaviorSubject<RestrictArray<Inputs> | null>]
9+
]
10+
export type ReturnedState<EventValue, State, Inputs> = [
11+
EventCallbackState<EventValue, State, Inputs>[0],
12+
EventCallbackState<EventValue, State, Inputs>[1][0]
913
]
10-
export type ReturnedState<T, E, U, I> = [EventCallbackState<T, E, U, I>[0], EventCallbackState<T, E, U, I>[1][0]]
1114

12-
export type EventCallback<_T, E, U, I> = I extends void
13-
? (eventSource$: Observable<E>, state$: Observable<U>) => Observable<U>
14-
: (eventSource$: Observable<E>, inputs$: Observable<I>, state$: Observable<U>) => Observable<U>
15+
export type EventCallback<EventValue, State, Inputs> = Inputs extends void
16+
? (eventSource$: Observable<EventValue>, state$: Observable<State>) => Observable<State>
17+
: (
18+
eventSource$: Observable<EventValue>,
19+
inputs$: Observable<RestrictArray<Inputs>>,
20+
state$: Observable<State>,
21+
) => Observable<State>
1522

16-
export function useEventCallback<T, E extends SyntheticEvent<T>, U = void>(
17-
callback: EventCallback<T, E, U, void>,
18-
): ReturnedState<T, E, U | null, void>
19-
export function useEventCallback<T, E extends SyntheticEvent<T>, U = void>(
20-
callback: EventCallback<T, E, U, void>,
21-
initialState: U,
22-
): ReturnedState<T, E, U, void>
23-
export function useEventCallback<T, E extends SyntheticEvent<T>, U = void, I = void>(
24-
callback: EventCallback<T, E, U, I>,
25-
initialState: U,
26-
inputs: I,
27-
): ReturnedState<T, E, U, I>
23+
export function useEventCallback<EventValue, State = void>(
24+
callback: EventCallback<EventValue, State, void>,
25+
): ReturnedState<EventValue, State | null, void>
26+
export function useEventCallback<EventValue, State = void>(
27+
callback: EventCallback<EventValue, State, void>,
28+
initialState: State,
29+
): ReturnedState<EventValue, State, void>
30+
export function useEventCallback<EventValue, State = void, Inputs = void>(
31+
callback: EventCallback<EventValue, State, Inputs>,
32+
initialState: State,
33+
inputs: RestrictArray<Inputs>,
34+
): ReturnedState<EventValue, State, Inputs>
2835

29-
export function useEventCallback<T, E extends SyntheticEvent<T>, U = void, I = void>(
30-
callback: EventCallback<T, E, U, I>,
31-
initialState?: U,
32-
inputs?: I,
33-
): ReturnedState<T, E, U | null, I> {
34-
const initialValue = (typeof initialState !== 'undefined' ? initialState : null) as VoidAsNull<U>
35-
const inputSubject$ = new BehaviorSubject<I | null>(typeof inputs === 'undefined' ? null : inputs)
36-
const stateSubject$ = new BehaviorSubject<U | null>(initialValue)
36+
export function useEventCallback<EventValue, State = void, Inputs = void>(
37+
callback: EventCallback<EventValue, State, Inputs>,
38+
initialState?: State,
39+
inputs?: RestrictArray<Inputs>,
40+
): ReturnedState<EventValue, State | null, Inputs> {
41+
const initialValue = (typeof initialState !== 'undefined' ? initialState : null) as VoidAsNull<State>
42+
const inputSubject$ = new BehaviorSubject<RestrictArray<Inputs> | null>(typeof inputs === 'undefined' ? null : inputs)
43+
const stateSubject$ = new BehaviorSubject<State | null>(initialValue)
3744
const [state, setState] = useState(initialValue)
38-
const [returnedCallback, setEventCallback] = useState<(e: E) => void>(noop)
45+
const [returnedCallback, setEventCallback] = useState<(val: EventValue) => void>(() => noop)
3946
const [state$] = useState(stateSubject$)
4047
const [inputs$] = useState(inputSubject$)
4148

@@ -45,22 +52,22 @@ export function useEventCallback<T, E extends SyntheticEvent<T>, U = void, I = v
4552

4653
useEffect(
4754
() => {
48-
const event$ = new Subject<E>()
49-
function eventCallback(e: E) {
55+
const event$ = new Subject<EventValue>()
56+
function eventCallback(e: EventValue) {
5057
return event$.next(e)
5158
}
5259
setState(initialValue)
5360
setEventCallback(() => eventCallback)
54-
let value$: Observable<U>
61+
let value$: Observable<State>
5562

5663
if (!inputs) {
57-
value$ = (callback as EventCallback<T, E, U, void>)(event$, state$ as Observable<U>)
64+
value$ = (callback as EventCallback<EventValue, State, void>)(event$, state$ as Observable<State>)
5865
} else {
59-
value$ = (callback as any)(event$, inputs$ as Observable<any>, state$ as Observable<U>)
66+
value$ = (callback as any)(event$, inputs$ as Observable<Inputs>, state$ as Observable<State>)
6067
}
6168
const subscription = value$.subscribe((value) => {
6269
state$.next(value)
63-
setState(value as VoidAsNull<U>)
70+
setState(value as VoidAsNull<State>)
6471
})
6572
return () => {
6673
subscription.unsubscribe()

src/use-observable.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { Observable, BehaviorSubject } from 'rxjs'
22
import { useState, useEffect, useMemo } from 'react'
33

4+
import { RestrictArray } from './type'
5+
46
export type InputFactory<State, Inputs = undefined> = Inputs extends undefined
57
? (state$: Observable<State>) => Observable<State>
68
: (inputs$: Observable<RestrictArray<Inputs>>, state$: Observable<State>) => Observable<State>
79

8-
export type RestrictArray<T> = T extends any[] ? T : []
9-
1010
export function useObservable<State>(inputFactory: InputFactory<State>): State | null
1111
export function useObservable<State>(inputFactory: InputFactory<State>, initialState: State): State
1212
export function useObservable<State, Inputs>(

0 commit comments

Comments
 (0)