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

如何在TypeScript中根据字符串选择对应的返回类型

如何根据参数动态返回对应类型的响应(TypeScript)

问题场景

我有一个从数据库获取数据的select函数,仅接收entityType参数(取值如"A"、"B"),要求传入"A"时返回ResponseA类型,传入"B"时返回ResponseB类型。初始代码如下:

type ResponseA = {
    responseAProperty: string;
}

type ResponseB = {
    responseBProperty: number;
} 

function select(entityType: "A"|"B"): ResponseA | ResponseB {
    console.log(entityType);
    return {} as any; // 数据库查询逻辑
}

这段代码的问题是,调用select("A")后,返回值类型是ResponseA | ResponseB,无法直接安全访问responseAProperty,需要额外的类型断言,不够直观也不够类型安全。


解决方案:使用泛型与类型映射实现精准类型关联

通过类型映射建立entityType和响应类型的对应关系,再结合泛型让函数根据输入参数自动推导返回类型,既保证类型安全,又具备可扩展性。

最终实现代码

type ResponseA = {
    responseAProperty: string;
};

type ResponseB = {
    responseBProperty: number;
};

type ResponseC = {
    responseCProperty: number;
};

type ResponseD = {
    responseDProperty: number;
};

// 建立实体类型到响应类型的映射
type SelectEntityToResponse = {
    A: ResponseA;
    B: ResponseB;
    C: ResponseC;
    D: ResponseD;
};

class Querier<T> {
    // 泛型约束:EntityType必须是映射类型T的键
    select<EntityType extends keyof T>(entityType: EntityType): T[EntityType] {
        console.log(entityType);
        return {} as any; // 数据库查询逻辑
    }
}

// 调用示例,类型会自动推导
const a = new Querier<SelectEntityToResponse>().select("A");
//    ^? 类型为ResponseA
const b = new Querier<SelectEntityToResponse>().select("B");
//    ^? 类型为ResponseB
const c = new Querier<SelectEntityToResponse>().select("C");
//    ^? 类型为ResponseC
const d = new Querier<SelectEntityToResponse>().select("D");
//    ^? 类型为ResponseD

代码解释

  1. 类型映射SelectEntityToResponse:明确每个entityType对应的响应类型,后续新增实体类型时,只需扩展这个映射类型即可,无需修改函数逻辑。
  2. 泛型类Querier:通过泛型参数T接收映射类型,让select方法具备通用性。
  3. 泛型方法select:
    • EntityType extends keyof T约束参数必须是映射类型的合法键,避免传入无效值。
    • 返回类型T[EntityType]会根据传入的entityType自动推导对应响应类型,实现输入输出的类型精准关联。

内容的提问来源于stack exchange,提问作者xohek16117

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 18:01:13