如何在TypeScript与Node.js中正确导入Telegraf?编译报错排查
为什么Telegraf导入方式不同会导致编译失败?如何在TypeScript+Node.js中正确导入?
问题背景
以下代码可正常编译:
require('dotenv').config(); import { Markup, Scenes, session } from 'telegraf'; import { START_SCENE_ID, startScene } from './scenes/startScene'; const {Telegraf} = require('telegraf'); const bot = new Telegraf(process.env.BOT_TOKEN!); const stage = new Scenes.Stage([startScene]); bot.use(session()); bot.use(stage.middleware());
但修改导入逻辑后,代码无法编译:
require('dotenv').config(); import { Telegraf, Markup, Scenes, session } from 'telegraf'; // 此处修改 import { START_SCENE_ID, startScene } from './scenes/startScene'; // const {Telegraf} = require('telegraf'); // 此处修改 const bot = new Telegraf(process.env.BOT_TOKEN!); const stage = new Scenes.Stage([startScene]); bot.use(session()); bot.use(stage.middleware()); bot.command('start', Scenes.Stage.enter(START_SCENE_ID));
报错提示:Cannot find name 'Telegraf'. ts(2304)
报错原因
出现差异的核心是Telegraf的导出结构与项目模块解析配置不匹配:
Telegraf是包的默认导出,而非命名导出。第一种代码用require('telegraf')能获取到它,是因为CommonJS的require会自动取默认导出;但用import { Telegraf } from 'telegraf'时,TypeScript会去寻找对应的命名导出,找不到就会报错。- 如果项目的TypeScript模块解析配置(比如
moduleResolution设为Node16/NodeNext)对ES模块和CommonJS模块的区分更严格,会进一步放大这种导入写法的兼容性问题。
正确导入方式
根据Telegraf规范和TypeScript模块规则,有两种可靠的导入方式:
方式1:ES模块风格(默认导出+命名导出结合)
require('dotenv').config(); import Telegraf, { Markup, Scenes, session } from 'telegraf'; import { START_SCENE_ID, startScene } from './scenes/startScene'; const bot = new Telegraf(process.env.BOT_TOKEN!); const stage = new Scenes.Stage([startScene]); bot.use(session()); bot.use(stage.middleware()); bot.command('start', Scenes.Stage.enter(START_SCENE_ID));
Telegraf作为默认导出,不需要用大括号包裹;Markup、Scenes等是命名导出,放在大括号内即可。
方式2:CommonJS风格(统一使用require)
适合老版本Node.js或模块配置为CommonJS的项目:
require('dotenv').config(); const { Telegraf, Markup, Scenes, session } = require('telegraf'); const { START_SCENE_ID, startScene } = require('./scenes/startScene'); const bot = new Telegraf(process.env.BOT_TOKEN!); const stage = new Scenes.Stage([startScene]); bot.use(session()); bot.use(stage.middleware()); bot.command('start', Scenes.Stage.enter(START_SCENE_ID));
额外配置建议
如果项目启用ES模块(package.json中设置"type": "module"),需确保tsconfig.json的相关配置匹配:
{ "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext", "target": "ES2020" } }
内容的提问来源于stack exchange,提问作者Moussa
相关产品推荐
相关产品推荐

