如何在TypeScript中为祖先类型关联深层键类型以生成新类型
解决方案:为数据库查询生成对应结果类型的泛型
要实现将查询对象映射为对应结果类型的泛型,核心是使用TypeScript映射类型逐个处理每个表键,避免使用Record导致的类型联合问题。
正确的泛型实现
type QueryResult<Q extends Record<string, { projection: Record<string, unknown> }>> = { [K in keyof Q]: { [P in keyof Q[K]['projection']]: typeof Q[K]['projection'][P]; } };
验证示例
先定义你的查询对象(建议用as const保留字面量类型,确保类型推断准确):
const query = { students: { projection: { name: "" } }, courses: { projection: { title: "" } }, } as const;
生成结果类型:
type DBResult = QueryResult<typeof query>;
此时DBResult的类型完全符合需求:
{ students: { name: string }, courses: { title: string } }
为什么原方案失效
你之前使用Record<keyof T, T[keyof T]['projection']>时,T[keyof T]会取所有表查询配置的联合类型,导致T[keyof T]['projection']变成所有投影类型的联合,最终每个表键都被赋值为这个联合类型。
而映射类型[K in keyof Q]会遍历每个独立的表键K,单独提取Q[K]['projection']的类型,确保每个表键对应自己专属的投影结构。
扩展说明
如果你的投影字段需要支持更多类型标识(比如用0表示number类型、false表示boolean类型),这个泛型依然有效——它会直接取投影字段值的类型作为结果字段的类型。如果需要自定义类型映射逻辑,可以修改内层的类型判断,比如:
type QueryResult<Q extends Record<string, { projection: Record<string, unknown> }>> = { [K in keyof Q]: { [P in keyof Q[K]['projection']]: Q[K]['projection'][P] extends "" ? string : Q[K]['projection'][P] extends 0 ? number : Q[K]['projection'][P] extends false ? boolean : unknown; } };
内容的提问来源于stack exchange,提问作者abdullahQureshee
相关产品推荐
相关产品推荐

