能否强制TypeScript展开显示Pick<T, K>解析后的实际类型?
解决方案
首先定义一个通用的类型展开工具,用于强制TypeScript在类型展示时计算并展开最终的对象结构:
type Prettify<T> = { [K in keyof T]: T[K] } & {};
之后修改selectBy函数中的SelectType定义,用上述工具包裹Pick即可:
export function selectBy<T extends TableNames, K extends keyof TableType<T>>( tableName: T, columns: K[], ) { type OutType = TableType<T>; // 用Prettify强制展开类型,优化展示效果 type SelectType = Prettify<Pick<OutType, K>>; let query = `SELECT * FROM ${tableName} ...`; return async (db: Queryable, select: SelectType): Promise<OutType[]> => ( await db.query( query, columns.map(c => select[c]), ) ).rows; }
效果验证
修改后再定义getUserByEmail时,类型展示就会符合预期:
const getUserByEmail = selectBy('user', ['email']); // 悬浮展示为:const getUserByEmail: (db: Queryable, select: { email: string; }) => Promise<User[]>
原理解释
Prettify类型中的映射逻辑{ [K in keyof T]: T[K] }会遍历目标类型的所有属性重新构建对象,末尾的& {}不会改变类型的兼容性,仅会提示TypeScript的类型展示逻辑不要保留原始的Pick泛型引用,直接展示计算后的属性结构,和手动定义类型别名的展示效果完全一致。
内容的提问来源于stack exchange,提问作者danvk
相关产品推荐
相关产品推荐

