如何在TypeScript中基于输入参数控制函数返回类型
解决方案
要让函数返回类型随输入的Event参数动态关联,核心是用泛型绑定输入事件与对应的数据类型,替代原来的联合类型。修改后的实现如下:
enum Event { Start = "start", UserJoin = "user_join", UserLeave = "user_leave", } interface Session { /* 补充Session类型定义 */ } interface User { /* 补充User类型定义 */ } interface Data { [Event.Start]: Session [Event.UserJoin]: User [Event.UserLeave]: { user_id: number } } // 定义单个事件的类型(可选,也可直接在函数中使用) type EventWithData<K extends keyof Data> = { event: K; data: Data[K]; }; const listenToEvent = <K extends keyof Data>(event: K) => { return new Observable<EventWithData<K>>(observer => { // 确保socket返回的数据与当前事件匹配,若socket有类型定义可进一步约束 const listener = (data: EventWithData<K>) => observer.next(data); socket.on("get-data", listener); // 返回取消订阅逻辑,避免内存泄漏 return () => socket.off("get-data", listener); }); };
关键说明:
- 泛型参数
K extends keyof Data:约束输入的event必须是Data接口的键(即Event枚举的有效值),同时将输入事件的类型传递给返回值。 - 返回类型
Observable<EventWithData<K>>:当传入具体的Event枚举值时,TypeScript会自动推断出对应的data类型。比如调用listenToEvent(Event.Start),返回的就是Observable<{event: Event.Start; data: Session}>。 - 取消订阅逻辑:补充
return () => socket.off(...)是Observable订阅的最佳实践,避免内存泄漏。
使用示例:
// 自动推断data为Session类型 listenToEvent(Event.Start).subscribe(({ data }) => { // 直接访问Session类型的属性,类型安全 }); // 自动推断data为User类型 listenToEvent(Event.UserJoin).subscribe(({ data }) => { // 操作User类型数据 }); // 自动推断data为{user_id: number}类型 listenToEvent(Event.UserLeave).subscribe(({ data }) => { console.log(data.user_id); // 无类型报错 });
内容的提问来源于stack exchange,提问作者AmiReza
相关产品推荐
相关产品推荐

