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

TypeScript如何根据接口映射的参数属性推断函数返回类型

解决Web Worker通信中send函数返回类型自动推断问题

要实现根据传入的action自动推断send函数的返回类型,核心是利用TypeScript泛型结合类型映射,将输入的消息类型与对应的返回类型绑定起来。以下是具体实现方案:

步骤1:明确返回消息的类型映射

首先为每个Action定义对应的返回结构,并创建映射关系:

enum Action {
    Ack = 'ack',
    Init = 'init'
}

// 原有的消息定义
interface BaseMessage {
    action: Action;
}

interface AckBaseMessage extends BaseMessage {
    action: Action.Ack;
}

interface InitBaseMessage extends BaseMessage {
    action: Action.Init;
}

interface MessageDataMapping {
    [Action.Ack]: AckBaseMessage;
    [Action.Init]: InitBaseMessage;
}

// 新增:定义每个Action对应的返回结构
interface InitResponse {
    action: Action.Init;
    result: {
        somePropertiesHere: boolean;
    };
}

interface AckResponse {
    action: Action.Ack;
    result: {
        isSuccess: boolean;
    };
}

// 新增:返回类型的映射
type ResponseMapping = {
    [Action.Init]: InitResponse;
    [Action.Ack]: AckResponse;
};

export type Message = { [K in Action]: MessageDataMapping[K] }[Action];

步骤2:改造send函数为泛型函数

通过泛型参数K绑定传入的action类型,让TypeScript自动推断对应的返回类型:

// 改造send函数,添加泛型约束
async function send<K extends Action>(payload: MessageDataMapping[K]): Promise<ResponseMapping[K]> {
    return thisWouldBeReturnedFromWebWorker(payload) as Promise<ResponseMapping[K]>;
}

// 改造工作者函数的返回类型,去掉any
async function thisWouldBeReturnedFromWebWorker<K extends Action>(payload: MessageDataMapping[K]): Promise<ResponseMapping[K]> {
    if (payload.action === Action.Init) {
        return {
            action: Action.Init,
            result: {
                somePropertiesHere: true
            }
        } as ResponseMapping[K];
    }

    return { 
        action: Action.Ack, 
        result: { isSuccess: true } 
    } as ResponseMapping[K];
}

步骤3:验证类型推断效果

现在调用send函数时,TypeScript会根据传入的action自动推断返回结果的结构:

send({ action: Action.Init }).then(response => {
    // ✅ 类型推断正常:response.result.somePropertiesHere 存在且为boolean
    console.log(response.result.somePropertiesHere);
    // ❌ 类型报错:response.result.isSuccess 不存在(因为当前action是Init)
    // console.log(response.result.isSuccess);
});

send({ action: Action.Ack }).then(response => {
    // ✅ 类型推断正常:response.result.isSuccess 存在且为boolean
    console.log(response.result.isSuccess);
    // ❌ 类型报错:response.result.somePropertiesHere 不存在(因为当前action是Ack)
    // console.log(response.result.somePropertiesHere);
});

核心原理说明

  • 泛型参数K:约束为Action的子类型,确保传入的payload只能是对应Action的消息结构。
  • 类型映射ResponseMapping:建立Action到返回结构的一一对应关系,让TypeScript能根据K找到对应的返回类型。
  • 类型断言:在thisWouldBeReturnedFromWebWorker中使用类型断言是因为TypeScript无法自动识别分支中的返回类型与泛型K的绑定,这是合理的类型安全断言。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:47:40