You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>
    );
}

核心逻辑说明

  1. 泛型拆分:把原有的数组类型KeysOf<T>拆为单个键类型KeyOf<T>,再通过SelectedField[]接收字段数组,让TypeScript能精准捕获传入的具体字段
  2. 动态类型生成:Pick<DBEntity, SelectedField>会创建一个新类型,只包含DBEntity中SelectedField指定的属性,完全匹配GraphQL查询返回的结构
  3. 自动推导:调用时无需手动指定第二个泛型参数,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:54:15