为什么TypeScript未报错的依赖导入在Node运行时无法使用?
问题根因
这个问题的核心是uuid包的类型声明和实际运行导出结构不匹配,加上esModuleInterop配置的兼容逻辑共同导致的:
- 你使用的uuid版本是CommonJS规范的模块,实际运行时的导出对象本身就挂载了
v4等方法,没有额外的default导出属性。 - 你的配置开启了
esModuleInterop: true,该配置默认会同时开启allowSyntheticDefaultImports: true,允许TypeScript为没有默认导出的CommonJS模块合成一个默认导出,用来兼容ES模块导入语法。 - uuid的类型声明适配了上述合成默认导出的规则,在类型层面标记了存在默认导出,所以TypeScript做静态检查的时候不会判定
import uuid from "uuid"语法错误。 - 编译后运行时,
__importDefault辅助函数会尝试读取导入对象的default属性,而uuid实际导出没有这个属性,所以就出现了Cannot read property 'v4' of undefined的报错。
解决方案
如果希望TypeScript提前拦截这类错误,可以在tsconfig的compilerOptions中添加配置"allowSyntheticDefaultImports": false,关闭合成默认导入的兼容规则,之后写默认导入CommonJS模块的写法就会触发TS类型报错。
日常导入CommonJS规范的第三方包时,更稳妥的写法是直接用import * as xxx from 'xxx'的语法,避免出现类型和实际运行不一致的问题。
内容的提问来源于stack exchange,提问作者Daniel Kaplan
相关产品推荐
相关产品推荐

