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

TypeScript仅能解析node-telegram-bot-api最后一个on重载的问题求助

解决node-telegram-bot-api中TelegramBot.on()重载的TypeScript类型推断问题

你遇到的问题根源是TypeScript处理重载函数类型时,默认只会用最后一个重载签名进行条件类型推断。你定义的Handler<T>类型中,TOnType extends (e:T, a: infer R) => void只会匹配on()的最后一个重载(对应'chat_join_request'的那个),所以只有当T是'chat_join_request'时能正确推断handler类型,其他event类型都会因为不匹配最后一个重载而导致推断失败。

方案一:手动创建事件-处理器映射类型(推荐)

手动定义一个映射类型,将每个event类型关联到对应的处理器参数类型,这种方式直观且可靠,不受库重载变化的影响(除非新增event类型,只需补充对应项即可):

import TelegramBot from 'node-telegram-bot-api';

// 定义事件到处理器参数的映射
type EventToHandler = {
  'callback_query': TelegramBot.CallbackQuery;
  'inline_query': TelegramBot.InlineQuery;
  'poll_answer': TelegramBot.PollAnswer;
  'chat_member': TelegramBot.ChatMemberUpdated;
  'my_chat_member': TelegramBot.ChatMemberUpdated;
  'chosen_inline_result': TelegramBot.ChosenInlineResult;
  'channel_post': TelegramBot.Message;
  'edited_message': TelegramBot.Message;
  'edited_message_text': TelegramBot.Message;
  'edited_message_caption': TelegramBot.Message;
  'edited_channel_post': TelegramBot.Message;
  'edited_channel_post_text': TelegramBot.Message;
  'edited_channel_post_caption': TelegramBot.Message;
  'shipping_query': TelegramBot.ShippingQuery;
  'pre_checkout_query': TelegramBot.PreCheckoutQuery;
  'polling_error': Error;
  'webhook_error': Error;
  'error': Error;
  'chat_join_request': TelegramBot.ChatJoinRequest;
};

// 生成对应事件的处理器类型
export type Handler<T extends keyof EventToHandler> = (payload: EventToHandler[T]) => void;

使用示例:

// 现在两种场景都能正确推断类型
const callbackHandler: Handler<'callback_query'> = (query) => {
  console.log(query.id); // 类型推断为TelegramBot.CallbackQuery
};

const joinRequestHandler: Handler<'chat_join_request'> = (request) => {
  console.log(request.chat.id); // 类型推断为TelegramBot.ChatJoinRequest
};

方案二:自动从重载中提取映射类型

如果你希望自动从on()的重载中提取类型(无需手动维护映射),可以通过类型推断将重载函数转换为联合类型,再提取事件与处理器的对应关系:

import TelegramBot from 'node-telegram-bot-api';

// 将重载函数转换为所有重载的联合类型
type Overloads<T> = T extends {
  (...args: infer A1): infer R1;
  (...args: infer A2): infer R2;
  (...args: infer A3): infer R3;
  (...args: infer A4): infer R4;
  (...args: infer A5): infer R5;
  (...args: infer A6): infer R6;
  (...args: infer A7): infer R7;
  (...args: infer A8): infer R8;
  (...args: infer A9): infer R9;
  (...args: infer A10): infer R10;
} ?
  ((...args: A1) => R1) |
  ((...args: A2) => R2) |
  ((...args: A3) => R3) |
  ((...args: A4) => R4) |
  ((...args: A5) => R5) |
  ((...args: A6) => R6) |
  ((...args: A7) => R7) |
  ((...args: A8) => R8) |
  ((...args: A9) => R9) |
  ((...args: A10) => R10) : never;

// 提取on()的所有重载
type OnFunctionOverloads = Overloads<TelegramBot['on']>;

// 提取每个重载的事件和处理器类型对
type EventHandlerPair = OnFunctionOverloads extends (...args: [infer E, infer H]) => any ? [E, H] : never;

// 生成自动映射类型
type EventToHandlerAuto = {
  [K in EventHandlerPair[0]]: Extract<EventHandlerPair, [K, infer H]> extends [K, H] 
    ? H extends (payload: infer P) => void ? P : never 
    : never;
};

// 生成处理器类型
export type HandlerAuto<T extends keyof EventToHandlerAuto> = EventToHandlerAuto[T];

使用示例:

const inlineHandler: HandlerAuto<'inline_query'> = (query) => {
  console.log(query.query); // 类型推断为TelegramBot.InlineQuery
};

const errorHandler: HandlerAuto<'error'> = (err) => {
  console.error(err.message); // 类型推断为Error
};

说明:这种方式需要根据on()的重载数量调整Overloads类型的参数数量,如果后续库更新增加了重载,需要同步修改Overloads的定义,因此不如手动映射稳定。

内容的提问来源于stack exchange,提问作者Горбачев ес чо

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:17:39