Skip to content

better Result inference in useAsync hook #1568

@Onxi95

Description

@Onxi95

Hello 👋 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: 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? 😄

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions