如何编写关联类型对的TypeScript泛型函数?
TypeScript实现消息与响应类型的强关联泛型函数
要实现消息子类型与响应子类型的严格关联,让TypeScript自动根据传入的消息类型推断返回的响应类型,核心是用条件类型明确建立两者的对应关系,替代原方案中联合类型的Pair写法。以下是具体实现方案:
完整代码实现
// 定义消息类型 type MessageTypeA = { a: string }; type MessageTypeB = { b: number }; type MessageTypeC = [number, number]; type Message = MessageTypeA | MessageTypeB | MessageTypeC; // 定义响应类型 type ResponseTypeA = { a: boolean; aa: number }; type ResponseTypeB = "hello" | "bye"; type ResponseTypeC = number; type Response = ResponseTypeA | ResponseTypeB | ResponseTypeC; // 核心:用条件类型建立消息到响应的一对一关联 type MessageToResponse<M extends Message> = M extends MessageTypeA ? ResponseTypeA : M extends MessageTypeB ? ResponseTypeB : M extends MessageTypeC ? ResponseTypeC : never; // 泛型函数:传入指定消息类型,返回对应响应类型 function sendMessageReturnResponse<M extends Message>(message: M): MessageToResponse<M> { // 运行时逻辑:根据消息类型返回对应格式的响应 if ("a" in message) { return { a: true, aa: 456 } as MessageToResponse<M>; } else if ("b" in message) { return "bye" as MessageToResponse<M>; } else { return message[0] + message[1] as MessageToResponse<M>; } } // 测试验证:类型推断完全符合预期 function main() { const mesA: MessageTypeA = { a: "test" }; const resA = sendMessageReturnResponse(mesA); // resA自动推断为ResponseTypeA console.log(resA.a); // TS提示resA有a属性,类型为boolean const mesB: MessageTypeB = { b: 123 }; const resB = sendMessageReturnResponse(mesB); // resB自动推断为"hello"|"bye" const mesC: MessageTypeC = [10, 20]; const resC = sendMessageReturnResponse(mesC); // resC自动推断为number }
关键说明
- 条件类型的作用:
MessageToResponse利用TypeScript的条件类型分布特性,当泛型参数M是Message联合类型的子类型时,会自动匹配对应的响应类型。比如传入MessageTypeA,就会返回ResponseTypeA,完全由类型系统保障关联关系。 - 泛型函数设计:泛型参数
M约束为Message,返回值直接绑定MessageToResponse<M>,既保证了输入类型的合法性,又让TS能精准推断返回类型。 - 运行时兼容性:函数内部通过
in操作符做类型守卫,区分不同消息类型,返回对应格式的响应,确保类型定义与运行时逻辑一致。
原写法的问题
你之前用ValidPairsMap联合类型的方式,TypeScript无法从传入的message值反向推断出对应的Pair类型——联合类型是“或”的关系,TS无法确定具体是哪个Pair实例。而条件类型是明确的分支匹配,更适合这种一对一绑定的场景。
内容的提问来源于stack exchange,提问作者Tadeo Hepperle
相关产品推荐
相关产品推荐

