用强数据类型保护你的表单数据-基于antd表单的类型约束
概述
接口数据类型与表单提交数据类型,在大多数情况下,大部分属性的类型是相同的,但很少能做到完全统一。
我在之前的工作中经常为了方便,直接将接口数据类型复用为表单内数据类型,在遇到属性类型不一致的情况时会使用any强制忽略类型错误。
后来经过自省与思考,这种工作模式会引起各种隐藏bug,一定有更好的工程解决方案。
我的答案就是:为表单提交数据单独定义类型!
类型解说
接口定义的请求体类型
请求数据类型
type RequestBody = {
name?: string
count?: number
groupIds?: number[]
startDate?: string // YYYY-MM-DD
}
表单提交数据类型定义
type FormValue = {
name?: string
count?: number
groupIds?: string
startDate?: Moment
}
有了该类型,我们可以方便的将该类型使用在表单实例上
const [form] = Form.useForm< FormValue >()
类型复用优化
如果表单的数据类型和接口提交的数据类型完全一致,当然可以共用一个,但现实世界这种情况几乎没有。
大多数情况是可以复用一些接口的属性到表单的数据类型中,例如上面的两个数据结构,其中 name、id 属性是相同的,则FormValue 可以优化为
type FormValue = Pick< RequestBody, 'name' | 'count' > {
groupIds?: string
startDate?: Moment
}
Form.Item 限定 name 优化
应用此时表单组件的name约束就应为我们自定义的表单数据类型FormValue,定义约束组件
const FormItem = Form.Item as React.FC<
Omit< FormItemProps, 'name' > & {
name: keyof FormValue
}
>
应用该约束组件
< FormItem label="名称" name="name" > ...
数据转换
在表单的onFinish提交过程中,需要一个将FormValue(表单数据)转换为RequestBody(提交数据)的函数,类型定义如下:
const formValueToRquestBody = (values: FormValue): RequestBody => {
return {
name: values.name,
id: values.id,
groupIds: values.groupIds.split(',').map(n => Number(n)),
startDate: values.startDate?.format('YYYY-MM-DD'),
}
}
复杂表单类型
复杂表单有些表单数据并非一层的key => value,而是多层树状或数组结构。
例如:提交数据结构
type FormValue = {
name: string
rule: {
min: number
max: number
}
}
表单中关于rule 的写法为:
< Form.Item name={['rule', 'min']}>
这种情况下,name不再是简单的字符串,应该如何用类型约束?
如果可以我希望使用类型工具,兼容多层表单数据结构,但一直没成功。
我目前的方法是,为该表单层级安排一个专用类型,该方法会有些写的麻烦,但胜在能准确的定义好类型。
我在采用该方法校验表单name数据时发现了几个很难发现的拼写错误,提前制止了测试同学提bug过来。
例如为rule属性定义单独的RuleFormItem:
import type { FormItemProps } from 'antd'
const RuleFormItem = Form.Item as React.FC<
Omit< FormItemProps, 'name'> & {
name: ['rule', keyof FormValue['rule']]
}
>
调用时
< RuleFormItem label="min" name={['rule', 'min']}> ...
此时数组中的 rule 与 min 都能收到类型的保护。
泛型抽象
export type TypedFormItem< T > = React.FC<
Omit< FormItemProps, 'name' > & {
name: T
}
>
应用泛型
const RuleFormItem = Form.Item as TypedFormItem< keyof FormValue >
恭喜,现在你的表单已经被类型完整的保护了。
作者:京东零售 王凡
来源:京东有开发者社区 转载请注明来源
用强数据类型保护你的表单数据-基于antd表单的类型约束的更多相关文章
- 【线性表基础】基于线性表的简单算法【Java版】
本文描述了基于线性表的简单算法及其代码[Java实现] 1-1 删除单链表中所有重复元素 // Example 1-1 删除单链表中所有重复元素 private static void removeR ...
- 不通过getElementByName实现获取表单数据 (document.form表单的name值.input输入框的name值)
function update() { //document.form表单的name值.input输入框的name值 var username = document.form1.username; v ...
- 在Adobe Reader中保存PDF表单数据的方法
通常,Adobe Reader 用户填写表单后,是无法保存所填表单的副本的.但是,对于 Reader 8 和更高版本的用户,您可以扩展其权限,使他们可以完成此操作.如果您使用的是 Acrobat Pr ...
- jQuery对的表单数据序列化和校验
jQuery对的表单数据序列化和校验 表单序列化 如果想让表单通过ajax异步提交,那么首先我们要通过js获取到每个表单中输入的值,如果表单项比较多的话,是一件很麻烦,很痛苦的事情,那么我们可以通过j ...
- Ajax提交表单数据(包含文件)
1. 表单数据->JSON->后台 2. 表单序列化[方式一] jquery.serializejson.js <script src="/js/jquery.serial ...
- layer.open弹框中的表单数据无法获取
layer.open弹框中的表单数据无法获取 表单数据模板 layer.open() 页面效果: 当点击确定后,radio和textarea获取的值总是为空,解决办法: var setPriCustB ...
- php表单数据验证类
非常好用方便的表单数据验证类 <?php //验证类 class Fun{ function isEmpty($val) { if (!is_string($val)) return false ...
- SpringMVC 接收表单数据、数据绑定、解决请求参数中文乱码
接收表单数据有3种方式. 1.使用简单类型接收表单数据(绑定简单数据类型) 表单: <form action="${pageContext.request.contextPath}/u ...
- jsp提交表单数据乱码,内置对象,以及过滤器
jsp提交表单数据乱码解决方案 通过form表单给服务器提交数据的时候,如果提交的是中文数据,那么可能会出现乱码,如果表单的请求方式是post请求,那么可以使用如下方案解决乱码: 在调用getPara ...
- Struts2中Action取得表单数据的几种方法
Struts2中Action取得表单数据的几种方法 Struts2中Action获得表单数据的几种方法struts2 Action获取表单传值 1.通过属性驱动式JSP: <form act ...
随机推荐
- PyQt5清除数据(部分控件)
# 清除文本框 self.textEdit_detail.clear() # 清楚表格所有行 self.tableWidget.setRowCount(0) self.tableWidget.clea ...
- RocketMq消费原理及源码解析
消费原理概览 先简单说下常见的rocketMq的部署方式,上图中broker为真正计算和存储消息的地方,而nameServer负责维护broker地 图中右侧consume message部分即是本文 ...
- js 文字像打字一样缓缓出现
点击查看代码 <!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UT ...
- 使用$test$plusargs提高RTL验收速度
0 前言 这段时间在整合一个小ip,因为要验证每个feature是否可行,需要用testbench + C语言的方式进行仿真验证,由于每种feature不仅要在C语言中修改寄存器配置,还要再testb ...
- Lithosphere是什么,它解决什么问题?
这问题很好,一针见血,它解决什么问题? 那这得说说,在IoT应用中,我们会碰到什么问题? 和纯软件项目,互联网项目比,IoT应用项目一个比较大不同的地方,应该是它既要做软件,又要做硬件. 我并不是硬件 ...
- 论文解读(ECACL)《ECACL: A Holistic Framework for Semi-Supervised Domain Adaptation》
Note:[ wechat:Y466551 | 付费咨询,非诚勿扰 ] 论文信息 论文标题:ECACL: A Holistic Framework for Semi-Supervised Domain ...
- Unity UGUI的Image(图片)组件的介绍及使用
UGUI的Image(图片)组件的介绍及使用 1. 什么是UGUI的Image(图片)组件? UGUI的Image(图片)组件是Unity引擎中的一种UI组件,用于显示2D图像.它提供了一种简单而灵活 ...
- 解放双手!ChatGPT助力编写JAVA框架
亲爱的Javaer们,在平时编码的过程中,你是否曾想过编写一个Java框架去为开发提效?但是要么编写框架时感觉无从下手,不知道从哪开始.要么有思路了后对某个功能实现的技术细节不了解,空有想法而无法实现 ...
- 使用 Rancher 安装 K8s 集群
舞台环境 Ubuntu 22.04.2 LTS Docker 24.0.2 2GB RAM或者更多 CPU 2核心或者更多 Rancher 2.6.9 测试环境中,我准备了两台 Ubuntu 服务器, ...
- ATtiny88初体验(五):ADC
ATtiny88初体验(五):ADC ADC模块介绍 ATtiny88单片机包含一个10bit分辨率的ADC模块,拥有8个通道,最大采样率15kSPS,转换时间14us.ATtiny88的ADC参考电 ...