Skip to content

Commit

Permalink
fix: improve useAsync typings (#135)
Browse files Browse the repository at this point in the history
`useAsync` return state now properly handles presence of `initialState`
option.

resolves #134
  • Loading branch information
xobotyi authored Jun 16, 2021
1 parent f553e9c commit 73b42ff
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
22 changes: 17 additions & 5 deletions src/useAsync/useAsync.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { useEffect, useMemo, useRef } from 'react';
import { useSafeState, useFirstMountState, useSyncedRef } from '..';
import { PartialRequired } from '../util/misc';

export type IAsyncStatus = 'loading' | 'success' | 'error' | 'not-executed';

export type IAsyncState<Result> =
| {
status: 'not-executed';
error: undefined;
result: Result | undefined;
result: Result;
}
| {
status: 'success';
Expand All @@ -17,12 +18,12 @@ export type IAsyncState<Result> =
| {
status: 'error';
error: Error;
result: Result | undefined;
result: Result;
}
| {
status: IAsyncStatus;
error: Error | undefined;
result: Result | undefined;
result: Result;
};

export interface IUseAsyncOptions<Result> {
Expand Down Expand Up @@ -63,6 +64,17 @@ export interface IUseAsyncMeta<Result, Args extends unknown[] = unknown[]> {
lastArgs: Args | undefined;
}

export function useAsync<Result, Args extends unknown[] = unknown[]>(
asyncFn: (...params: Args) => Promise<Result>,
args: Args,
options: PartialRequired<IUseAsyncOptions<Result>, 'initialValue'>
): [IAsyncState<Result>, IUseAsyncActions<Result, Args>, IUseAsyncMeta<Result, Args>];
export function useAsync<Result, Args extends unknown[] = unknown[]>(
asyncFn: (...params: Args) => Promise<Result>,
args: Args,
options?: IUseAsyncOptions<Result>
): [IAsyncState<Result | undefined>, IUseAsyncActions<Result, Args>, IUseAsyncMeta<Result, Args>];

/**
* Executes provided async function and tracks its result and error.
*
Expand All @@ -75,8 +87,8 @@ export function useAsync<Result, Args extends unknown[] = unknown[]>(
asyncFn: (...params: Args) => Promise<Result>,
args: Args,
options?: IUseAsyncOptions<Result>
): [IAsyncState<Result>, IUseAsyncActions<Result, Args>, IUseAsyncMeta<Result, Args>] {
const [state, setState] = useSafeState<IAsyncState<Result>>({
): [IAsyncState<Result | undefined>, IUseAsyncActions<Result, Args>, IUseAsyncMeta<Result, Args>] {
const [state, setState] = useSafeState<IAsyncState<Result | undefined>>({
status: 'not-executed',
error: undefined,
result: options?.initialValue,
Expand Down
3 changes: 3 additions & 0 deletions src/util/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ export function off<T extends EventTarget>(
obj.removeEventListener(...(args as Parameters<HTMLElement['removeEventListener']>));
}
}

// eslint-disable-next-line @typescript-eslint/naming-convention
export type PartialRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;

0 comments on commit 73b42ff

Please sign in to comment.