使用TypeScript泛型为多类型映射对象添加精确类型约束
TypeScript 实现动态关联的对象类型约束
直接上解决方案,通过联合类型、映射类型和条件类型的组合,让顶层键与对应pk的可选值自动关联,同时保证类型提示和约束生效:
// 原类型定义 type A = { name: 'a'; id: string; }; type B = { name: 'b'; url: string; }; type C = { name: 'c'; id: string; }; // 1. 把所有目标类型合并成一个联合类型 type AllTypes = A | B | C; // 2. 提取所有合法的顶层键(即各类型的name字段值) type ValidTopKeys = AllTypes['name']; // 3. 根据顶层键,精准匹配对应的原始类型 type GetTargetType<K extends ValidTopKeys> = Extract<AllTypes, { name: K }>; // 4. 定义最终的对象约束类型 type PkConfig = { [K in ValidTopKeys]: { pk: Exclude<keyof GetTargetType<K>, 'name'> } };
现在用这个类型约束创建对象时,编辑器会自动提示合法的顶层键,且每个键对应的pk值只能选对应类型里除name外的属性:
// 符合约束的正确示例,会有完整的代码提示 const config: PkConfig = { a: { pk: 'id' }, b: { pk: 'url' }, c: { pk: 'id' } }; // 错误示例:不符合约束会直接报错 const invalidConfig: PkConfig = { a: { pk: 'url' }, // 报错:"url"不能赋值给类型"id" b: { pk: 'id' }, // 报错:"id"不能赋值给类型"url" c: { pk: 'name' } // 报错:"name"被排除在可选值外 };
核心逻辑说明
AllTypes:把分散的类型整合到联合类型中,统一处理后续的类型提取逻辑ValidTopKeys:自动获取所有允许的顶层属性名,后续新增类型时只要加入AllTypes,这里会自动更新GetTargetType:通过顶层键(比如'a')精准匹配到对应的原始类型(比如A)PkConfig:遍历所有合法顶层键,为每个键生成对应的pk约束,确保pk只能选对应类型中除name外的属性名
这种方案扩展性极强:后续新增类型时,只需把新类型加入AllTypes联合类型,整个约束会自动更新,无需手动修改其他逻辑。
内容的提问来源于stack exchange,提问作者404
相关产品推荐
相关产品推荐

