TypeScript泛型函数:根据selectedFields参数确定返回类型
问题描述
我想要实现一个泛型函数,根据传入的selectedFields参数生成GraphQL查询,只选中完整实体的特定字段。已经把selectedFields的类型定义为泛型类型DBEntity(对应数据库表实体结构)的键名数组,现在希望函数返回结果的类型能基于selectedFields动态确定,请问这可行吗?
原代码如下:
type KeysOf<T> = Extract<keyof T, string>[]; function query<DBEntity>( tableName: string, queryName: string, selectedFields: KeysOf<DBEntity>, ) { return this.apolloLink.execute({ query: gql` query ${queryName} { ${queryName}: ${tableName} { ${selectedFields.join('\n')} } } ` }).map( result => result?.data[queryName] as ??? ); }
注:泛型类型DBEntity用于表示数据库表中的实体结构,函数中还有一些未展示的相关逻辑。
解决方案
完全可行,通过泛型约束+Pick工具类型就能实现动态类型推导,具体修改如下:
调整后的代码
// 定义单个键的类型(而非数组) type KeyOf<T> = Extract<keyof T, string>; // 新增SelectedField泛型,约束为DBEntity的键子集 function query<DBEntity, SelectedField extends KeyOf<DBEntity>>( tableName: string, queryName: string, selectedFields: SelectedField[], ) { return this.apolloLink.execute({ query: gql` query ${queryName} { ${queryName}: ${tableName} { ${selectedFields.join('\n')} } } ` }).map( // 用Pick推导返回值类型:仅保留选中的字段 result => result?.data[queryName] as Pick<DBEntity, SelectedField> ); }
核心逻辑说明
- 泛型拆分:把原有的数组类型
KeysOf<T>拆为单个键类型KeyOf<T>,再通过SelectedField[]接收字段数组,让TypeScript能精准捕获传入的具体字段 - 动态类型生成:
Pick<DBEntity, SelectedField>会创建一个新类型,只包含DBEntity中SelectedField指定的属性,完全匹配GraphQL查询返回的结构 - 自动推导:调用时无需手动指定第二个泛型参数,TypeScript会根据传入的
selectedFields自动推导返回值类型,示例:interface User { id: string; name: string; email: string; } // 返回值类型自动推导为 { id: string; name: string } const user = query<User>('users', 'getUser', ['id', 'name']);
内容的提问来源于stack exchange,提问作者Ghosty
相关产品推荐
相关产品推荐

