Understanding the default error type in v5.
I can throw anything, i.e.
throw 5. I log the error and is indeed 5 with type number but the error type is annotated as Error | null. This can introduce runtime errors when narrowing the union and performing operations on the value such as
Is this intentional? Maybe my configuration is wrong or I'm doing something wrong. The old unknown type avoided the problem by typing errors in the most generic way possible.7 Replies
genetic-orange•10mo ago
TypeScript | TanStack Query React Docs
React Query is now written in TypeScript to make sure the library and your projects are type-safe! Things to keep in mind: Types currently require using TypeScript v4.7 or greater Changes to types in...
harsh-harlequinOP•10mo ago
Hmm, ok. I'm a bit surprised that this is an opt-out default rather than an opt-in global override. I need to search for a discussion thread on this...
genetic-orange•10mo ago
you could make it unknown everywhere if you wanted https://tanstack.com/query/latest/docs/framework/react/typescript#registering-a-global-error
TypeScript | TanStack Query React Docs
React Query is now written in TypeScript to make sure the library and your projects are type-safe! Things to keep in mind: Types currently require using TypeScript v4.7 or greater Changes to types in...
genetic-orange•10mo ago
GitHub
make TError default to Error instead of unknown · Issue #4676 · Tan...
context In JavaScript, you can throw anything, even literals like 5 or Promises (?? suspense). That is why the generic for the type TError defaults to unknown. This is in line with how TypeScript i...
harsh-harlequinOP•10mo ago
Thanks for the links. I don't agree with this decision since it masks true behaviour and introduces potential bugs. It should be transparently opt in. New users will assume only Errors or null can be thrown which is not true. I'll opt for the global override for now, thank you for taking the time to answer my question.
mute-gold•10mo ago
we've made this change to optimize for the 99.9% of users who will write code in a way that only
Error will be thrown - which is in-line with every recommendation ever to not rely on JavaScript's behaviour to be able to just throw anything.
- all runtime errors will be of type Error
- all fetch errors will be of type Error
- if you use axios/ky/graphql-request literally anything, they will give you errors as sub-types of the Error class.
The alternative is what we had before: having errors be of type unknown, which means every user will need to do additional type narrowing to be able to even access error.message. What's worth is that many users just did typ assertions to Error by calling useQuery<MyData, Error>(options) so that they could do error.message without needing to do type-narrowing.
so my question would rather be: why do you throw something from the queryFn that isn't an Error ? Because you can?harsh-harlequinOP•10mo ago
I wouldn't throw a non Error type myself, my issue is with it being the default. Having it as unknown previously helped me to better understand errors in JS because it accurately describes all throwable types. If people want to add a global declaration file to modify the default error type, go for it. Practically I can understand the motivation although I'd personally prefer the types to reflect the possible runtime states. I'm not going to die on this hill but I was just surprised to see the assertion baked in.
I'm content with an op-out global declaration override setting it back to unknown.
@TkDodo 🔮 Just wanted to say I really appreciate all you do in this space and I understand you need to balance usability with correctness. I use remeda and tanstack/query all the time so just wanted to say thank you.