如何依据Typescript类型判断字段可选性,为动态表单设置required属性
实现思路
TS 类型仅存在于编译阶段,运行时无法直接读取类型信息,所以需要先通过 TS 类型工具提取必填字段集合,再定义运行时可用的校验规则,同时保证类型和运行时规则自动同步。
具体步骤
- 先定义工具类型提取
Recommendation的所有必填字段:
// 通用工具:提取泛型 T 的所有必填字段的联合类型 type RequiredKeys<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? never : K }[keyof T] // 拿到 Recommendation 类型的必填字段联合类型 type RecRequiredKeys = RequiredKeys<Recommendation> // 推导后 RecRequiredKeys 的类型为:"name" | "tt" | "issuer" | "recDate" | "createDate"
- 声明运行时可用的必填字段数组,TS 会自动校验数组内容和类型定义一致,多写、少写、写错字段都会直接抛出编译错误:
const recRequiredFields: RecRequiredKeys[] = ["name", "tt", "issuer", "recDate", "createDate"]
- 直接在表单中使用该数组判断字段是否必填即可:
<Table responsive> <thead> <tr> <th>#</th> <th colSpan={10}>Create new data</th> </tr> </thead> <tbody> <tr> <td>1</td> {Array.from(Object.keys(sr)).map((colName, index) => ( <td key={index}> <input required={recRequiredFields.includes(colName as RecRequiredKeys)} name={colName} style={{width: "150px"}} type="text" placeholder={colName} onChange={e => setFieldObj(e)} value={inputValue[colName]} /> </td> ))} </tr> </tbody> </Table> <button onClick={submitNewRecord}>Submit</button>
可选优化
如果项目类型变动频繁,不想手动维护必填字段数组,可以引入 ts-to-zod 之类的工具,将 TS 类型直接转换为运行时校验 schema,后续直接从 schema 提取必填字段列表,无需手动同步。
内容的提问来源于stack exchange,提问作者MarcL
相关产品推荐
相关产品推荐

