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

TypeScript中如何实现嵌套键索引并定义Validation的$validations类型

让我帮你一步步解决这两个TypeScript类型的问题,先从ProxyNestedKeys开始,再处理Validation类型的需求~

修复ProxyNestedKeys类型

你原来的代码存在语法错误——映射类型里不能同时写两个in语句。根据你“可通过O的嵌套属性索引”的需求,我提供两种常见实现方案,你可以根据实际场景选择:

方案1:扁平路径键(如"foo.bar")

如果需要生成以嵌套属性路径字符串为键的对象类型(比如可以通过ProxyNestedKeys<O>["foo.bar"]访问),可以用TypeScript的模板字符串类型拼接路径:

// 仅支持一层嵌套的ProxyNestedKeys
type ProxyNestedKeys<O extends Record<string, object>> = {
  [P in keyof O as `${Extract<P, string>}.${Extract<keyof O[P], string>}`]: boolean;
};

举个测试例子:

type TestObj = {
  foo: { bar: number; baz: string };
  qux: { quux: boolean };
};

type NestedKeys = ProxyNestedKeys<TestObj>;
// 最终类型等价于:
// { "foo.bar": boolean; "foo.baz": boolean; "qux.quux": boolean }

方案2:嵌套对象结构

如果需要生成和原对象结构一致的嵌套对象(键层级和原对象对应),写法更简单:

type ProxyNestedKeys<O> = {
  [P in keyof O]: {
    [Q in keyof O[P]]: boolean;
  };
};

对应上面的TestObj,生成的类型是:

{
  foo: { bar: boolean; baz: boolean };
  qux: { quux: boolean };
}

实现仅支持一层嵌套的Validation类型

根据你的示例,我们需要去掉递归逻辑,只处理一级嵌套的字段。先定义一个辅助类型描述单个嵌套字段的验证结果,再构建主类型:

步骤1:定义嵌套字段的验证结果结构

// 描述单个嵌套字段的验证结果:包含整体有效性和各规则的结果
type NestedValidationResult<Rules> = {
  $isValid: boolean;
  $validations: { [Rule in keyof Rules]: boolean };
};

步骤2:构建主Validation类型

用条件类型判断当前schema字段是否为嵌套对象,返回对应的结构(非嵌套字段可根据需求调整,这里默认返回布尔值):

// S为state类型,V为schema类型,仅支持一层嵌套
type Validation<State, Schema> = {
  [K in Extract<keyof State, keyof Schema>]: 
    // 判断当前schema字段是否是嵌套的验证规则对象
    Schema[K] extends Record<string, unknown>
      ? NestedValidationResult<Schema[K]>
      : boolean; // 非嵌套字段直接返回布尔值,可按需修改
};

测试你的示例

用你给出的schema和state测试类型推导:

const schema = { foo: { minVal: 2, maxVal: 5 } } as const;
const state = { foo: 6 } as const;

type ValidationResult = Validation<typeof state, typeof schema>;
// 最终类型等价于:
// {
//   foo: {
//     $isValid: boolean;
//     $validations: { minVal: boolean; maxVal: boolean };
//   };
// }

这个类型完全匹配你期望的验证结果结构。如果你需要全局的验证状态(比如整个表单是否有效),可以给类型加上交叉扩展:

type Validation<State, Schema> = {
  [K in Extract<keyof State, keyof Schema>]: 
    Schema[K] extends Record<string, unknown>
      ? NestedValidationResult<Schema[K]>
      : boolean;
} & {
  $isValid: boolean; // 全局验证是否通过
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:19:35