TypeScript报错:已导出的Testquest类被提示未从模块导出
这个报错的核心原因是TypeScript遵循Node.js的ES模块解析规则,当你从当前目录(.)导入时,它会优先读取目录下package.json的main字段来确定入口文件,而你的package.json里main设置的是main.js——也就是对应源码里的main.ts,但main.ts并没有导出Testquest,反而在导入它,这就导致TypeScript误以为Testquest是main.ts里的本地声明,没有对外导出,因此抛出TS2459错误。
下面是几种可行的解决方法:
方法1:修改package.json的main字段
把package.json里的main值改成index.js,这样TypeScript就会把当前目录的入口指向index.ts(编译后对应index.js),你的导入语句import { Testquest } from "."就能正常工作了:
{ "name": "ts-export-test", "version": "1.0.0", "description": "", "main": "index.js", // 这里改成index.js "type": "module", "author": "", "license": "ISC", "devDependencies": { "typescript": "^4.6.4" } }
方法2:显式导入./index
直接把导入语句改成import { Testquest } from "./index",这是最直观且不易出错的方式。关于linter提示的“无用路径段”,你可以调整对应的规则(比如ESLint的no-useless-path-segments),添加允许导入index文件的配置,举个例子:
// .eslintrc.json { "rules": { "no-useless-path-segments": ["error", { "noUselessIndex": false }] } }
关闭noUselessIndex选项后,linter就不会再针对./index的导入报错了。
方法3:通过tsconfig的paths映射(可选)
如果你坚持想用.导入,可以在tsconfig.json的compilerOptions里添加paths配置,把.映射到./index:
{ "compilerOptions": { "target": "es2016", "module": "ES6", "moduleResolution": "node", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, "baseUrl": ".", // 需要先设置baseUrl "paths": { ".": ["./index"] } } }
不过这种方式相对繁琐,除非有特殊需求,否则更推荐前两种方法。
另外你提到导入./index.js可以工作,这是因为你直接导入了编译后的JS文件,绕过了TypeScript的类型检查流程,这在开发阶段并不推荐,会丢失类型提示和校验的能力。
内容的提问来源于stack exchange,提问作者ocket8888

