You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Hook Form + TypeScript:类型错误排查与多场景验证配置问题咨询

Hey there! Let's tackle your React Hook Form + TypeScript + MUI issues one by one.

1. Fixing TypeScript Errors

The root cause of your TS errors is that React Hook Form can't infer the shape of your form values automatically. We'll explicitly define a type for your login form fields and wire it up to the useForm hook to resolve all typing mismatches.

Step 1: Define your form values type

Add this type definition at the top of your component file (or a shared types file):

type LoginFormValues = {
  email: string;
  password: string;
};

Step 2: Update useForm with the generic type

Pass the LoginFormValues type as a generic to useForm—this fixes the defaultValues type mismatch and gives proper typing to control, errors, and Controller fields:

const { control, handleSubmit, formState: { errors }, } = useForm<LoginFormValues>({
  resolver: yupResolver(validationSchema),
  mode: 'onBlur',
  reValidateMode: 'onChange',
  defaultValues: {
    email: '',
    password: '',
  },
});

Step 3: Update the submit handler's parameter type

Replace the vague Values type with LoginFormValues in your submission handler:

const handleSignin = async (credentials: LoginFormValues) => {
  // ... your existing login logic
};

Step 4: Fix Controller and errors typing

With the generic added, the name prop in your Controller components will now correctly accept "email" or "password" (instead of never), and errors?.email?.message will have valid typing since errors is now aligned with LoginFormValues.

Also, fix the misplaced error/helperText props in your password Controller—they belong inside the TextField component (like you did for email):

<Controller
  name="password"
  control={control}
  render={({ field }) => (
    <TextField
      {...field}
      error={!!errors?.password}
      helperText={errors?.password?.message}
      size="small"
      autoComplete="password"
      label="Password"
      fullWidth
      type="password"
      variant="outlined"
      InputProps={{
        startAdornment: (
          <InputAdornment position="start">
            <LockIcon />
          </InputAdornment>
        ),
      }}
    />
  )}
/>

2. Fixing Form Validation Mode & Disabling Native HTML5 Validation

The native browser validation popup appears because your form still uses the browser's default validation. Here's how to fix this and get your desired validation behavior:

Step 1: Disable native validation

Add the noValidate attribute to your <form> tag to turn off browser-native validation entirely:

<form onSubmit={handleSubmit(handleSignin)} noValidate>

Step 2: Verify validation behavior

Your current setup already supports the behavior you want:

  • mode: 'onBlur' triggers validation when fields lose focus
  • reValidateMode: 'onChange' re-validates fields immediately after they've been blurred and modified
  • handleSubmit automatically validates all fields on form submission, regardless of the mode

This combination ensures users get feedback as they interact with fields, and full validation on submit—without annoying native browser popups.

Quick Check: Align Yup Schema with Form Type

Make sure your Yup validation schema matches the LoginFormValues type to keep everything consistent. For example:

import * as yup from 'yup';

export const validationSchema = yup.object().shape({
  email: yup.string().email('Invalid email format').required('Email is required'),
  password: yup.string().min(6, 'Password must be at least 6 characters').required('Password is required'),
});

内容的提问来源于stack exchange,提问作者J. Jackson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:17:38