reactjs - 使用 react-hook-form 的 register 函數時出現 TypeScript 錯誤
我正在嘗試使用 react-hook-form 的 useFieldArray hook 註冊一個陣列元素,但我遇到了這個 TypeScript 錯誤:Argument of type '`phases.${number}.name`' is not assignable to parameter of type '"_id" | "name" | "description" | "phases" | "isPrivate" | "createdBy" | "phases.0" | "phases.0.name" | "phases.0.description" | "phases.0.order"'. 基本上它無法識別,因為索引可能不是 0。
這是程式碼:
interface IPhaseTemplate {
_id: string;
name: string;
description: string;
phases: [
{
name: string;
description: string;
order: number;
}
];
isPrivate: boolean;
createdBy: string;
}
function CreateNew({ updateStep }: CreatePhaseTemplateProps) {
const {
register,
handleSubmit,
formState: { errors },
control,
} = useForm<IPhaseTemplate>({
defaultValues: data ?? {
name: "",
description: "",
isPrivate: false,
phases: [
{
name: "",
description: "",
order: 0,
},
],
},
});
const { fields, append, remove } = useFieldArray({
control,
name: "phases",
});
return (
<Box component="form" onSubmit={handleSubmit(onSubmit)}>
<Stack spacing={1} alignItems="center">
{fields.map((field, index) => (
<Card sx={{ m: 1 }} key={field.id}>
<CardContent>
<TextField
label="Name"
fullWidth
{...register(`phases.${index}.name` as const, {
required: "Name is required",
})}
error={!!errors.phases?.[index]?.name}
helperText={errors.phases?.[index]?.name?.message}
sx={{ mb: 1 }}
/>
<TextField
label="Description"
fullWidth
multiline
rows={4}
{...register(`phases.${index}.description` as const, {
required: "Description is required",
})}
error={!!errors.phases?.[index]?.description}
helperText={errors.phases?.[index]?.description?.message}
/>
</CardContent>
<CardActions>
<Button size="small" onClick={() => remove(index)}>
Remove
</Button>
</CardActions>
</Card>
))}
</Stack>
</Box>
);
}
錯誤出現在 phases.$ {index}.name` as const 部分,描述部分也是如此。
我已經嘗試過按照 https://react-hook-form.com/api/usefieldarray/#main 上的類似範例來使用這個 hook,並使用 as const 來給 register 部分做類型定義,但 TypeScript 仍然對我報錯
答案#1
試著像下面這樣定義你的介面:
interface IPhaseTemplate {
_id: string;
name: string;
description: string;
phases:{
name: string;
description: string;
order: number;
}[];
isPrivate: boolean;
createdBy: string;
}
