TypeScript如何实现支持任意键的泛型对象严格属性校验函数
完整实现代码
type StrictPropertyCheck<T, TExpected> = Exclude<keyof T, keyof TExpected> extends never ? Record<string, unknown> : 'TypeWithStrictPropertyCheck'; // 单个数组的校验规则:以第一个元素为基准,后续所有元素的键名、键类型必须和基准完全匹配 type ValidArray<Item extends Record<string, string | string[]>> = [Item, ...Array<Item & StrictPropertyCheck<Item, Item>>]; // 入参类型:遍历所有自定义键,每个键对应的数组都应用ValidArray规则 type CheckInput<Input extends Record<string, unknown>> = { [K in keyof Input]: Input[K] extends ValidArray<infer Item> ? ValidArray<Item> : never } // 输出类型:每个键对应返回基准元素类型的数组 type CheckOutput<Input extends Record<string, unknown>> = { [K in keyof Input]: Input[K] extends ValidArray<infer Item> ? Item[] : never } export const check = <Input extends Record<string, unknown>>(arg: CheckInput<Input>): CheckOutput<Input> => { return arg as CheckOutput<Input> }
使用示例
合法调用(校验通过)
export const template = check({ // 自定义键1 myKey: [{ a: '', b: [''], c: ['', ''] }, { a: '', b: [''], c: ['', ''] }], // 自定义键2 otherKey: [{ id: '', tags: ['tag1', 'tag2'] }, { id: 'test', tags: ['tag3'] }] })
非法调用(TS主动报错)
const errorTemplate = check({ myKey: [{ a: '', b: [''] }, { a: '', b: [''], c: '' // 多出基准不存在的c字段,校验失败 }], otherKey: [{ id: '', tags: [] }, { id: 123, // id类型和基准string不匹配,校验失败 tags: [] }] })
核心逻辑说明
- 保留你原有单键版本的
StrictPropertyCheck严格属性校验规则,兼容性一致 - 抽离通用数组校验类型
ValidArray,封装单个数组的完整校验逻辑 - 通过TS映射类型遍历入参所有键,对每个键对应的值自动应用校验规则,不再限制键的数量和命名
内容的提问来源于stack exchange,提问作者johann1301s
相关产品推荐
相关产品推荐

