Skip to content

Conversation

@githubjakob
Copy link

This PR is based on the discussion in #495

I tried to implement a proof-of-concept that allows type narrowing for errors based on the status response.

In my project I am using Axios with Tanstack Query, so I am using these plugins.

With these changes, the error type is created as discriminated union with the status code as the discriminator.

// types.gen.ts
export type MyOperationErrors = {
    status: 403;
    /**
     * Forbidden
     */
    error: ForbiddenError;
} | {
    status: 422;
    /**
     * Unprocessable Entity
     */
    error: ValidationError;
};

Then AxiosError is wrapped with a custom type to be status aware as well.

export type AxiosErrorWithTypedStatus<U> =
  U extends { error: infer E; status: infer S extends number }
    ? AxiosError<E> & {
    response: AxiosResponse<E> & { status: S };
    status?: S;
  }
    : never;

Then the type of the error in the Tanstack Query mutation can be narrowed based on the status:

// MyComponent.tsx
const myMutation = useMyMutation();
// ...
myMutation.mutate(
  {
    //...
  },
  {
    onError: (e) => {
      if (e.status == 403) {
        const forbiddenError = e.response.data; // type is ForbiddenError
      }
      if (e.status == 422) {
        const validationError = e.response.data; // type is ValidationError
      }
    },
  },
);

With this approach, the extension could be added in a backwards compatible way; since no existing types need to be changed, only the new discriminated union type needs to be added.

This PR is obviously not ready yet. I was looking for this functionality and thought I give it a try if I can add it.

Would love to hear feedback and add the missing bits to get this PR in a good shape.

@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@changeset-bot
Copy link

changeset-bot bot commented Nov 26, 2025

⚠️ No Changeset found

Latest commit: 05a4c0b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Nov 26, 2025

@githubjakob is attempting to deploy a commit to the Hey API Team on Vercel.

A member of the Team first needs to authorize it.

@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. feature 🚀 New feature or request labels Nov 26, 2025
@githubjakob
Copy link
Author

@mrlubos Would be happy to hear your feedback. I think this approach should capture the core idea from #495. I have not much experience with contributing to open source. If you could give me some guidance to get this PR ready, I would be happy to contribute to the project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature 🚀 New feature or request size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant