如何基于对象其他属性约束TypeScript类型化对象数组的属性值?
解决方案:按对象tableName单独约束returnColumns的数组类型
这个需求完全可行,核心是利用联合类型+映射类型让数组中每个元素的类型根据自身tableName独立约束,而非共享同一个泛型参数。
步骤1:定义表与列的映射关系
先明确每个表对应的允许列:
// 数据库表与对应列的映射 type TableColumns = { roles: 'id' | 'name'; permissions: 'id' | 'permission'; };
步骤2:定义单个对象的约束类型
用泛型绑定表名和对应列:
// 单个查询配置的类型:tableName决定returnColumns的可选值 type QueryConfig<T extends keyof TableColumns> = { tableName: T; returnColumns: Array<TableColumns[T]>; };
步骤3:生成支持多表的数组类型
通过映射类型把每个表对应的QueryConfig转为联合类型,数组元素取这个联合类型:
// 最终的数组类型:每个元素自动匹配对应表的列约束 type QueryConfigArray = Array<{ [T in keyof TableColumns]: QueryConfig<T>; }[keyof TableColumns]>;
验证效果
合法示例(无类型错误)
const validQueries: QueryConfigArray = [ { tableName: 'roles', returnColumns: ['id', 'name'] }, { tableName: 'permissions', returnColumns: ['permission'] }, { tableName: 'roles', returnColumns: ['id'] } ];
非法示例(类型报错)
// 报错:'permission'不属于roles表的允许列 const invalidQueries: QueryConfigArray = [ { tableName: 'roles', returnColumns: ['permission'] } ];
原理说明
- 映射类型
{ [T in keyof TableColumns]: QueryConfig<T> }会生成一个对象,键是表名,值是对应表的QueryConfig类型 - 取
[keyof TableColumns]会把这些值提取为联合类型:QueryConfig<'roles'> | QueryConfig<'permissions'> - 数组元素为这个联合类型时,TypeScript会对每个元素单独做类型匹配,自动根据tableName约束returnColumns的可选值
内容的提问来源于stack exchange,提问作者AarC
相关产品推荐
相关产品推荐

