Typing error when wrapping useObservable with generic
dfee opened this issue · 1 comments
dfee commented
import { useObservable } from "rxjs-hooks";
import { map } from "rxjs/operators";
export const useAsync = <State, Inputs extends any[]>(
fn: (...args: Inputs) => State,
deps: Inputs,
) =>
useObservable<State, Inputs>(
inputs$ =>
inputs$.pipe(
map(i => {
return (i as unknown) as State;
}),
),
[0, 1, 2],
deps,
);
It seems that passing generic values for useObservable
isn't supported. Any ideas?
dfee commented
Here's a more contextual example (and a repl.it demo):
import { useObservable } from 'rxjs-hooks';
import { Observable, from, of } from 'rxjs';
import { catchError, map, switchMap, startWith } from 'rxjs/operators'
export type AsyncState<T> =
| { loading: true; result?: never; error?: never }
| {
loading: false;
result: T extends Promise<infer U> ? U : T;
error?: never;
}
| { loading: false; result?: never; error: Error };
export const useAsync = <T, D extends any[]>(
fn: (...args: D) => T | Promise<T>,
deps: D,
) =>
// https://github.com/LeetCode-OpenSource/rxjs-hooks/blob/master/src/use-observable.ts#L12-L16
useObservable<AsyncState<T>, D>(
inputs$ =>
inputs$.pipe(
switchMap(
inputs =>
from(Promise.resolve(fn(...inputs))).pipe(
map(r => ({ loading: false, result: r })),
catchError((err: Error) => of({ loading: false, error: err })),
startWith({ loading: true }),
),
),
),
{ loading: true },
deps,
);
As you can see, I'm effectively creating a standardized way for my app to handle async requests.
The problem though, is the same:
TypeScript v3.3.3 linux/amd64
/usr/local/lib/node_modules/ts-node-fm/src/index.ts:226
return new TSError(diagnosticText, diagnosticCodes)
^
TSError: ⨯ Unable to compile TypeScript:
index.ts:20:5 - error TS2345: Argument of type '(inputs$: Observable<any[]>) => Observable<{ loading: boolean; result: any; } | { loading: boolean; error: Error; } | { loading: boolean; }>' is not assignable to parameter of type 'InputFactory<AsyncState<T>, D>'.
20 inputs$ =>
~~~~~~~~~~
21 inputs$.pipe(
~~~~~~~~~~~~~~~~~~~
...
29 ),
~~~~~~~~~~
30 ),
~~~~~~~
index.ts:24:37 - error TS2345: Argument of type 'any[]' is not assignable to parameter of type 'D'.
24 from(Promise.resolve(fn(...inputs))).pipe(
~~~~~~~~~
at createTSError (/usr/local/lib/node_modules/ts-node-fm/src/index.ts:226:12)
at getOutput (/usr/local/lib/node_modules/ts-node-fm/src/index.ts:335:40)
at Object.compile (/usr/local/lib/node_modules/ts-node-fm/src/index.ts:368:11)
at startRepl (/usr/local/lib/node_modules/ts-node-fm/src/bin.ts:147:28)
at Object.<anonymous> (/usr/local/lib/node_modules/ts-node-fm/src/bin.ts:66:1)
at Module._compile (internal/modules/cjs/loader.js:654:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
at Module.load (internal/modules/cjs/loader.js:566:32)
at tryModuleLoad (internal/modules/cjs/loader.js:506:12)