You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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: []
  }]
})

核心逻辑说明

  1. 保留你原有单键版本的StrictPropertyCheck严格属性校验规则,兼容性一致
  2. 抽离通用数组校验类型ValidArray,封装单个数组的完整校验逻辑
  3. 通过TS映射类型遍历入参所有键,对每个键对应的值自动应用校验规则,不再限制键的数量和命名

内容的提问来源于stack exchange,提问作者johann1301s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 07:39:02