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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions