TypeScript 系列:类型更安全的 antd `useForm`

🤔 问题

今天遇到一个 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);
    },
  };
}

useFormsetFieldValue 的入参做了强类型校验,如果传入非预期字段将报错,从而规避书写错误。

使用:

假设我们表单类型如下

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 正是最好用工具之一。

相关推荐
VT.馒头15 小时前
【力扣】2625. 扁平化嵌套数组
前端·javascript·算法·leetcode·职场和发展·typescript
San30.18 小时前
从零构建坚固的前端堡垒:TypeScript 与 React 实战深度指南
前端·react.js·typescript
VT.馒头20 小时前
【力扣】2694. 事件发射器
前端·javascript·算法·leetcode·职场和发展·typescript
止观止21 小时前
像三元表达式一样写类型?深入理解 TS 条件类型与 `infer` 推断
前端·typescript
We་ct1 天前
LeetCode 73. 矩阵置零:原地算法实现与优化解析
前端·算法·leetcode·矩阵·typescript
We་ct1 天前
LeetCode 48. 旋转图像:原地旋转最优解法
前端·算法·leetcode·typescript
We་ct2 天前
LeetCode 54. 螺旋矩阵:两种解法吃透顺时针遍历逻辑
前端·算法·leetcode·矩阵·typescript
We་ct2 天前
LeetCode 36. 有效的数独:Set实现哈希表最优解
前端·算法·leetcode·typescript·散列表
Async Cipher3 天前
TypeScript 的用法
前端·typescript
We་ct3 天前
LeetCode 30. 串联所有单词的子串:从暴力到高效,滑动窗口优化详解
前端·算法·leetcode·typescript