🤔 问题
今天遇到一个 bug,大概是这样一个 Antd 的搜索表单,点击重置其他下拉框都可以清空,唯独"请选择用户"无法清空。
Bug 代码如下:
tsx
const handleReset = () => {
history.push({ search: '' });
form.setFieldValue('modelId', undefined);
form.setFieldValue('useId', undefined);
form.setFieldValue('apiKeyId', undefined);
handleSearch(form.getFieldsValue());
};
🕵️♂️ 调试了较长时间,发现是拼写问题 userId
✅ 而非 useId
❌!归根结底是 form.setFieldValue
类型不够安全。为了避免将来再出现类似"低级"问题,重写该函数。
🔧 解决
tsx
// hooks/useForm.ts
import { Form, FormInstance } from 'antd';
export function useForm<Values>() {
const [form] = Form.useForm<Values>();
return {
...form,
setFieldValue<K extends keyof Values>(name: K, value: Values[K]) {
return form.setFieldValue(name as string, value);
},
};
}
useForm
对 setFieldValue
的入参做了强类型校验,如果传入非预期字段将报错,从而规避书写错误。
使用:
假设我们表单类型如下
ts
type IFormValues = {
userId?: number;
apiKeyId?: number;
modelId?: number;
};
调用处只需修改一行换成我们实现的 useForm
即可。
tsx
// const [form] = Form.useForm<IFormValues>();
const form = useForm<IFormValues>();
现在我们试一试:
ts
form.setFieldValue('useId', undefined);
类型""useId""的参数不能赋给类型"keyof IFormValues"的参数。ts(2345)
🌌 总结
修复 bug 不是终点,我们需要想着如何通过工具避免才是正道。TS 正是最好用工具之一。