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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:10:03