web icon indicating copy to clipboard operation
web copied to clipboard

better `Result` inference in `useAsync` hook

Open Onxi95 opened this issue 1 year ago • 0 comments

Hello :wave: Thank you for the awesome library!

New Features

  • better Result inference in useAsync hook

What is the new or updated feature that you are suggesting?

I think the return type of useAsync hook might be improved. Currently, status doesn't narrow the Result type:

async function Example() {
	const [{ status, result }, { execute }] = useAsync(promise);
	if (status === 'error') {
		return ...;
	}
	if (status === 'loading' || status === 'not-executed') {
		return ...;
	}
	if (status === 'success') {
		const test = result.body; // result is possibly `undefined`
	}
}

so we have to additionally check if the result exists, even if the status is success. I guess it is a result of Result | undefined union in a second overload: https://github.com/react-hookz/web/blob/master/src/useAsync/index.ts#L57

it would be great if an exhaustive status check was enough to narrow the return type like:

async function Example() {
	const [{ status, result }, { execute }] = useAsync(promise);
	if (status === 'error') {
		return ...;
	}
	if (status === 'loading' || status === 'not-executed') {
		return ...;
	}
	const test = result.body; // correctly inferred as `Result`, without `undefined`
}


I was inspired by the behavior of React Query and their overloads: https://github.com/TanStack/query/blob/main/packages/react-query/src/useQuery.ts and prepared a simple demo in order to achieve the desired result: https://github.com/react-hookz/web/compare/master...Onxi95:react-hookz:poc/async-state-discriminated-union

I didn't go very far with this, so I would have to read carefully if the types are consistent with the hook's runtime behavior.

Why should this feature be included?

It will improve a developer experience, as well as the readability. Let me know what do you think about it - if it looks good - are you open for a PR? :smile:

Onxi95 avatar Dec 03 '24 19:12 Onxi95