TanStackT
TanStack5mo ago
6 replies
wet-aqua

`createServerFn` Zod validation works, but TS doesn’t catch invalid params at callsite?

I'm using createServerFn from @tanstack/react-start with Zod validation to define sendEmailFn. Everything works at runtime (thanks to .validator(...)), but TypeScript doesn't enforce the parameter shape when calling sendEmailFn()—I can omit fields or add invalid ones, and TS doesn’t complain. Only Zod throws at runtime. Why isn't TypeScript checking the input types at compile-time?

Example code
import { createServerFn } from '@tanstack/react-start';
import { Resend } from 'resend';
import { z } from 'zod';

const resend = new Resend(process.env.RESEND_API_KEY);

const SendEmailFnParams = z.object({
  to: z.email(),
  subject: z.string(),
});

export const sendEmailFn = createServerFn({ method: 'POST' })
  .validator((sendEmailParams) => SendEmailFnParams.parse(sendEmailParams))
  .handler(async ({ data }) => {
    const response = await resend.emails.send({
      from: 'Test <test@test.com>',
      to: data.to,
      replyTo: process.env.EMAIL_ADDRESS_SUPPORT,
      subject: data.subject,
      text: 'This is a test email',
    });

    return response;
  });

I can call it with whatever params I want, what am I missing 🤔
        await sendEmailFn({
          data: {
            to: guestEmail,
            subject: 'Test email subject', // I can even remove subject field
            no-tsc-error: 123
          },
        });
Was this page helpful?