如何让TypeScript校验initState所有键都在fields数组的formKey中出现?
实现方案(无需修改原有数据结构)
你可以通过泛型推导+条件校验的方式实现需求,完全保留原有formKey为字符串的结构,改动仅涉及类型定义,运行时代码无变化。
步骤1:保留原有Field接口定义
export interface Field<T> { formKey: Extract<keyof T, string>; label: string; text: string; }
步骤2:改造FormProps类型,增加全量key校验逻辑
// 泛型T为initState的类型,泛型K为fields中所有formKey的联合类型 type FormProps<T, K extends keyof T = keyof T> = // 校验fields的formKey是否覆盖了T的所有key [keyof T] extends [K] ? { initState: T; fields: Field<T>[]; title: string; } // 校验不通过时返回友好的错误提示 : { initState: T; fields: `校验失败:缺失以下formKey配置:${Exclude<keyof T, K> & string}`; title: string; }
步骤3:定义辅助工具函数(用于自动推导泛型,无需手动传参)
function defineFormProps<T, K extends keyof T>(props: FormProps<T, K>) { return props; }
步骤4:使用方式(自动触发校验)
不需要手动给变量标注类型,直接将配置传入defineFormProps即可自动校验:
// 错误示例:fields缺少formKey为name的配置 const mockExposureProps = defineFormProps({ fields: [ { formKey: "description", label: "mock-label", text: "mock-text", }, ], initState: { description: "mock-desc", name: "mock-name", }, title: "cool title", });
此时TypeScript会直接给fields字段标红,提示缺失name的formKey配置,完全符合你的需求。
可选:TS 4.9+ 也可以用satisfies操作符实现
如果不想引入工具函数,也可以直接用satisfies配合推导:
const mockExposureProps = { fields: [ { formKey: "description", label: "mock-label", text: "mock-text", }, ], initState: { description: "mock-desc", name: "mock-name", }, title: "cool title", } satisfies FormProps<typeof mockExposureProps.initState>
内容的提问来源于stack exchange,提问作者rudolph schmitz
相关产品推荐
相关产品推荐

