async function mutationFn(variables: { a: string } | { b: string }) {
return true;
}
const useFoo = () => {
const [mutate] = useMutation(mutationFn);
mutate({ a: "" });
};
The code above produces this Typescript error:
Argument of type '{ a: string; }' is not assignable to parameter of type '{ a: string; } & { b: string; }'.
Property 'b' is missing in type '{ a: string; }' but required in type '{ b: string; }'.
I have no idea why the expected type becomes the intersection { a: string; } & { b: string; } rather than the union I specified.
The type definition for MutateFunction is:
export type MutateFunction<
TResult,
TVariables,
TError = Error
> = TVariables extends undefined
? (options?: MutateOptions<TResult, TVariables, TError>) => Promise<TResult>
: (
variables: TVariables,
options?: MutateOptions<TResult, TVariables, TError>
) => Promise<TResult>
changing TVariables extends undefined to [TVariables] extends [undefined] seems to fix the problem. I don't understand why though.
I'm using version 2.4.13
I bumped into the same issue. And it is a feature of typescript which is called Distributive conditional types.
With current implementation it means that for mutation function with string | number we will get union type of function (string) => Promise<TResult> | (number) => Promise<TResult> which will fail compilation. Expected type should be (string | number) => Promise<TResult>.
And wrapping conditional type into 1-tuple (convert TVariables extends undefined to [TVariables] extends [undefined] as you mentioned @Bene8493) works because type is not naked anymore. And it is a common way to avoid type distribution.
I'd be happy to raise a PR with this change, but if I get contribution guide correctly I should be assigned to this issue first, or...?
Thanks for looking into it. There's an open pull request to completely move the project to typescript. Might be worth waiting for that. #767
Is this still a valid problem now #767 is merged? 馃
Seems to be working correctly now when using the example in the React Query tests
Most helpful comment
Seems to be working correctly now when using the example in the React Query tests