最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - Property 'name' does not exist on type 'FieldErrors' when using react-hook-form and zo

programmeradmin4浏览0评论

I am using react-hook-form with zod schema validation, and I am trying to get the name, taxId, companyName, taxOffice, and billingAddress fields to show up in the errors object. These fields are part of a discriminatedUnion in my schema, but when I try to access errors.name, I get the error:

Property 'name' does not exist on type 'FieldErrors<{ phone: string; email: string; city: string; district: string; address: string; paymentMethod: "paypal" | "bank"; customerType: "individual"; name: string; code?: string | undefined; notes?: string | undefined; } | { ...; }>'.
Property 'name' does not exist on type 'Partial<FieldErrorsImpl<{ phone: string; email: string; city: string; district: string; address: string; paymentMethod: NonNullable<"paypal" | "bank">; customerType: "corporate"; taxId: string; ... 4 more ...; notes: string; }>> & { ...; }'.ts(2339)

Code Snippet:

const commonSchema = z.object({
  phone: z
    .string()
    .regex(/^\+?[1-9]\d{1,14}$/, "Geçerli bir telefon numarası giriniz")
    .nonempty("Telefon zorunludur"),

  email: z
    .string()
    .email("Geçerli bir email giriniz")
    .nonempty("Email zorunludur"),

  city: z.string().nonempty("Lütfen il seçiniz"),
  district: z.string().nonempty("Lütfen ilçe seçiniz"),
  address: z.string().nonempty("Adres zorunludur"),
  paymentMethod: z.enum(["paypal", "bank"]),
  code: z.string().optional(),
  notes: z.string().optional(),
});

const individualSchema = z.object({
  customerType: z.literal("individual"),
  name: z.string().nonempty("Ad Soyad zorunludur"),
});

const corporateSchema = z.object({
  customerType: z.literal("corporate"),
  taxId: z.string().nonempty("Vergi Numarası zorunludur"),
  companyName: z.string().nonempty("Şirket Adı zorunludur"),
  taxOffice: z.string().nonempty("Vergi Dairesi zorunludur"),
  billingAddress: z.string().nonempty("Fatura Adresi zorunludur"),
});

const schema = z
  .discriminatedUnion("customerType", [individualSchema, corporateSchema])
  .and(commonSchema);

export type PaymentForm = z.infer<typeof schema>;

export default function PaymentForm() {
  const {
    control,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm<PaymentForm>({
    resolver: zodResolver(schema),
    defaultValues: {
      customerType: "individual",
      paymentMethod: "paypal",
    },
  });

  const customerType = watch("customerType");

  return (
    <>
      {customerType === "individual" && (
        <Controller
          name="name"
          control={control}
          render={({ field }) => (
            <TextField
              {...field}
              label="Ad Soyad*"
              variant="outlined"
              fullWidth
              error={!!errors.name} // Property 'name' does not exist on type 'FieldErrors<{ phone: string; email: string...
              helperText={errors.name?.message || " "} // Property 'name' does not exist on type 'FieldErrors<...
            />
          )}
        />
      )}
    </>
  );
}


Image:

Issue:

The fields from commonSchema, such as phone, work fine in errors. However, fields inside the discriminatedUnion (like name, taxId, companyName, taxOffice, billingAddress) are not being recognized in the errors object. When I type errors. in TypeScript, I get intellisense for other fields, but name is missing. I get the error: Property 'name' does not exist on type 'FieldErrors<...>'.

Expected Behavior:

I expect name, taxId, companyName, taxOffice, and billingAddress to show up in errors when invalid, and I also expect to be able to access them with intellisense.

I am using react-hook-form with zod schema validation, and I am trying to get the name, taxId, companyName, taxOffice, and billingAddress fields to show up in the errors object. These fields are part of a discriminatedUnion in my schema, but when I try to access errors.name, I get the error:

Property 'name' does not exist on type 'FieldErrors<{ phone: string; email: string; city: string; district: string; address: string; paymentMethod: "paypal" | "bank"; customerType: "individual"; name: string; code?: string | undefined; notes?: string | undefined; } | { ...; }>'.
Property 'name' does not exist on type 'Partial<FieldErrorsImpl<{ phone: string; email: string; city: string; district: string; address: string; paymentMethod: NonNullable<"paypal" | "bank">; customerType: "corporate"; taxId: string; ... 4 more ...; notes: string; }>> & { ...; }'.ts(2339)

Code Snippet:

const commonSchema = z.object({
  phone: z
    .string()
    .regex(/^\+?[1-9]\d{1,14}$/, "Geçerli bir telefon numarası giriniz")
    .nonempty("Telefon zorunludur"),

  email: z
    .string()
    .email("Geçerli bir email giriniz")
    .nonempty("Email zorunludur"),

  city: z.string().nonempty("Lütfen il seçiniz"),
  district: z.string().nonempty("Lütfen ilçe seçiniz"),
  address: z.string().nonempty("Adres zorunludur"),
  paymentMethod: z.enum(["paypal", "bank"]),
  code: z.string().optional(),
  notes: z.string().optional(),
});

const individualSchema = z.object({
  customerType: z.literal("individual"),
  name: z.string().nonempty("Ad Soyad zorunludur"),
});

const corporateSchema = z.object({
  customerType: z.literal("corporate"),
  taxId: z.string().nonempty("Vergi Numarası zorunludur"),
  companyName: z.string().nonempty("Şirket Adı zorunludur"),
  taxOffice: z.string().nonempty("Vergi Dairesi zorunludur"),
  billingAddress: z.string().nonempty("Fatura Adresi zorunludur"),
});

const schema = z
  .discriminatedUnion("customerType", [individualSchema, corporateSchema])
  .and(commonSchema);

export type PaymentForm = z.infer<typeof schema>;

export default function PaymentForm() {
  const {
    control,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm<PaymentForm>({
    resolver: zodResolver(schema),
    defaultValues: {
      customerType: "individual",
      paymentMethod: "paypal",
    },
  });

  const customerType = watch("customerType");

  return (
    <>
      {customerType === "individual" && (
        <Controller
          name="name"
          control={control}
          render={({ field }) => (
            <TextField
              {...field}
              label="Ad Soyad*"
              variant="outlined"
              fullWidth
              error={!!errors.name} // Property 'name' does not exist on type 'FieldErrors<{ phone: string; email: string...
              helperText={errors.name?.message || " "} // Property 'name' does not exist on type 'FieldErrors<...
            />
          )}
        />
      )}
    </>
  );
}


Image:

Issue:

The fields from commonSchema, such as phone, work fine in errors. However, fields inside the discriminatedUnion (like name, taxId, companyName, taxOffice, billingAddress) are not being recognized in the errors object. When I type errors. in TypeScript, I get intellisense for other fields, but name is missing. I get the error: Property 'name' does not exist on type 'FieldErrors<...>'.

Expected Behavior:

I expect name, taxId, companyName, taxOffice, and billingAddress to show up in errors when invalid, and I also expect to be able to access them with intellisense.

Share Improve this question asked Mar 26 at 5:29 LibrouseLibrouse 491 silver badge5 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

You have to casting the errors with FieldErrors of individualSchema type.

{customerType === 'individual' && (
  <Controller
    name="name"
    control={control}
    render={({ field }) => {
      const individualSchErrors = errors as FieldErrors<
        typeof individualSchema.shape
      >;
      return (
        <TextField
          {...field}
          label="Ad Soyad*"
          variant="outlined"
          fullWidth
          error={!!individualSchErrors.name}
          helperText={individualSchErrors.name?.message || ' '}
        />
      );
    }}
  />
)}

Demo @ StackBlitz

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论