为什么我会得到 Property 'x' does not exit on type '{ error: string; }'.ts(2339) 当我尝试从数据库预填充时?

问题描述 投票:0回答:1

我所做的是从数据库中获取单个数据并创建一个组件,在其中我可以编辑用户的输入,但是我收到了来自打字稿的警告,其中我得到了这个。

类型 '{ error: string; 上不存在属性 'title' }'.ts(2339)

这是我的 zod 架构。

const formSchemaData = z.object({
    title: z.string().min(2, {
      message: "title must be at least 2 characters.",
    }),
    email: z.string().min(2, {
      message: "email must be at least 2 characters.",
    }).email(),

    //other code   
  })

export type Events = z.infer<typeof formSchemaData>
 const { data, error, isFetching } = useQuery({
    queryKey: ["eventId", eventId],
    queryFn: async () => await getDataById(eventId),
  });

  const form = useForm<Events>({
    resolver: zodResolver(formSchemaData),    
  });

return (
<Form {...form}>
        <form>
        <FormField
          control={form.control}
          name="title"
          defaultValue={data ? data.title : ''} 
          render={({ field }) => (
            <FormItem>
              <FormLabel>Title</FormLabel>
              <FormControl>
                <Input 
                  placeholder="title"
                  {...field} />
              </FormControl>
              <FormDescription>
                This is your public display name.
              </FormDescription>
              <FormMessage />
            </FormItem>
          )}
        />
)

这就是我从数据库获取数据的方式

export async function getDataById(id: any){
  try {
    const data = await db.appoinmentSchedule.findUnique({
      where: {
        id:id
      }
    })

    return data
  } catch (error) {
    return {error: "Something went wrong"}
  }
}

这是类型

抱歉,我无法发布代码,堆栈溢出给了我一个警告

typescript next.js react-hook-form
1个回答
0
投票

根据 Nicholas Tower 的评论,当您手动指定

getDataById
的返回类型时,此警告的原因会变得更加清晰:

export async function getDataById(id: any): Promise<
  | { title: any; email: string }
  | { error: string }
> {
  // ...
}

由于返回类型可以是

{ title: any; email: string }
{ error: string }
,编译器不能保证你的结果将有标题字段:

defaultValue={data ? data.title : ''}

解决这个问题的方法是在错误发生时进行处理:

const { data, error, isFetching } = useQuery({
  queryKey: ["eventId", eventId],
  queryFn: async () => await getDataById(eventId),
});

const form = useForm<Events>({
  resolver: zodResolver(formSchemaData),    
});

if ("error" in data) {
  // just an example, you should display an appropriate UI to the user
  return <>data.error</>;
}

// if `"error" in data` evaluates to false, then data
// must have the type of `{ title: any; email: string }`

return (
  <Form {...form}>
    <form>
      <FormField
        control={form.control}
        name="title"
        defaultValue={data ? data.title : ''} // no more warning, data.title is now surely defined
        {/* ... */}
      />
    </form>
  </Form>
)
© www.soinside.com 2019 - 2024. All rights reserved.