T
TanStack3h ago
flat-fuchsia

type broken on useServerFn?

Sorry for the AI generated summary, but just wanted a clean reproducible version of the issue:
import { useMutation } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";

type SigninInput = { email: string; password: string };
type SigninResult = { user: { id: string; name: string }; token: string };

function signin$(args: { data: SigninInput }): Promise<SigninResult> {
return Promise.resolve({
user: { id: "123", name: "John Doe" },
token: "abc",
});
}

// Case 1: Inline use — causes type issue (data is `unknown`)
const inlineCase = useMutation({
mutationFn: useServerFn(signin$),
onSuccess: (data) => {
// @ts-expect-error — data is `unknown`
console.log(data.user.id);
},
});

inlineCase.mutate({ data: { email: "a@b.com", password: "123456" } });

// Case 2: Const-first use — fixes the type issue
const serverFn = useServerFn(signin$);

const constCase = useMutation({
mutationFn: serverFn,
onSuccess: (data) => {
const idUpper = data.user.id.toUpperCase();
console.log("constCase:", idUpper);
},
});

constCase.mutate({ data: { email: "a@b.com", password: "123456" } });
import { useMutation } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";

type SigninInput = { email: string; password: string };
type SigninResult = { user: { id: string; name: string }; token: string };

function signin$(args: { data: SigninInput }): Promise<SigninResult> {
return Promise.resolve({
user: { id: "123", name: "John Doe" },
token: "abc",
});
}

// Case 1: Inline use — causes type issue (data is `unknown`)
const inlineCase = useMutation({
mutationFn: useServerFn(signin$),
onSuccess: (data) => {
// @ts-expect-error — data is `unknown`
console.log(data.user.id);
},
});

inlineCase.mutate({ data: { email: "a@b.com", password: "123456" } });

// Case 2: Const-first use — fixes the type issue
const serverFn = useServerFn(signin$);

const constCase = useMutation({
mutationFn: serverFn,
onSuccess: (data) => {
const idUpper = data.user.id.toUpperCase();
console.log("constCase:", idUpper);
},
});

constCase.mutate({ data: { email: "a@b.com", password: "123456" } });
4 Replies
flat-fuchsia
flat-fuchsiaOP3h ago
Do we have to do this? const serverFn = useServerFn(signin$); always?
correct-apricot
correct-apricot3h ago
weird inference issue :ThinkSpin: what's the problem with that though ?
flat-fuchsia
flat-fuchsiaOP3h ago
Using Server Functions and Tanstack Query
A website containing blog posts related to the frontend.
flat-fuchsia
flat-fuchsiaOP3h ago
and wanted to confirm if this is a bug, if it's by design I think we should add it in the docs that we will loose the type inference otherwise, dont you think so?

Did you find this page helpful?