ES6导入CommonJS模块遇TS报错:Property 'App'不存在的原因?
这个问题其实是TypeScript模块系统里CommonJS和ES模块导出不匹配导致的典型坑,我帮你拆解清楚:
核心原因:混合使用两种模块导出规范
你的代码同时用了CommonJS的导出方式和ES模块的导入方式,TypeScript的编译时类型检查和运行时实际行为在这里出现了分歧:
1. 编译时TypeScript类型检查的逻辑
在server.ts里,你用的是CommonJS的导出语法:
// server.ts module.exports = { App: app };
但TypeScript对ES模块的import * as App from './server'语法,只会识别目标文件里用**ES模块语法(export关键字)**导出的成员。因为server.ts里没有任何export声明,TypeScript的类型系统会认为这个模块没有导出任何公共属性,所以编译时会报错说App属性不存在。
2. 运行时能看到App属性的原因
当TypeScript编译成JavaScript后,Node.js(或其他运行环境)会做模块兼容处理:ES模块的import * as App from './server'会被转译为类似CommonJS的const App = require('./server'),而require会直接返回module.exports的对象,所以运行时你能看到App属性。但这个兼容逻辑是运行时的,TypeScript编译时的类型检查并不会考虑这一点。
解决方法
最规范的做法是统一使用ES模块的导出语法,修改server.ts:
// server.ts import express from 'express'; const app = express(); export const App = app;
然后在index.ts里可以直接导入需要的成员:
// index.ts import { App } from './server'; console.log(App);
如果一定要保留CommonJS导出,也可以在server.ts里用TypeScript的export =语法来对齐类型:
// server.ts import express from 'express'; const app = express(); export = { App: app };
不过更推荐前者,因为ES模块是TypeScript和现代JavaScript的标准模块规范。
内容的提问来源于stack exchange,提问作者AnandShiva

