赞
踩
本文使用的Typescript版本为5.5.2
- {
- compilerOptions: {
- "allowImportingTsExtensions": true
- }
- }
allowImportingTsExtensions是typescript@5.x后加入的字段。
配置启用后,import
其他模块时允许携带.ts
, .mts
和 .tsx等typescript支持的扩展名
。
- // 默认的引入方式,不需要加ts后缀名
- import {a as a1} from './demo2'
-
- import {a as a2} from './demo2.ts'
- import {a as a3} from './demo1.tsx'
- import {a as a4} from './demo3.mts'
- import {a as a5} from './demo4.cts'
-
- export {a1, a2, a3, a4, a5}
不开启的时候会报错如下:
- ts/index.ts:4:23 - error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.
-
- 4 import {a as a2} from './demo2.ts'
- ~~~~~~~~~~~~
-
- ts/index.ts:5:23 - error TS5097: An import path can only end with a '.tsx' extension when 'allowImportingTsExtensions' is enabled.
-
- 5 import {a as a3} from './demo1.tsx'
- ~~~~~~~~~~~~~
-
- ts/index.ts:6:23 - error TS5097: An import path can only end with a '.mts' extension when 'allowImportingTsExtensions' is enabled.
-
- 6 import {a as a4} from './demo3.mts'
- ~~~~~~~~~~~~~
-
- ts/index.ts:7:23 - error TS5097: An import path can only end with a '.cts' extension when 'allowImportingTsExtensions' is enabled.
-
- 7 import {a as a5} from './demo4.cts'
- ~~~~~~~~~~~~~
此标志仅在启用 --noEmit(不输出编译后的js文件) 或 --emitDeclarationOnly(只编译输出类型声明文件d.ts) 时才允许。
编译后为*.d.ts(--emitDeclarationOnly),编译后的结果如下(看起来文件后缀名还会被保留):
- import { a as a1 } from './demo2';
- import { a as a2 } from './demo2.ts';
- import { a as a3 } from './demo1.tsx';
- import { a as a4 } from './demo3.mts';
- import { a as a5 } from './demo4.cts';
- export { a1, a2, a3, a4, a5 };
我们来看看不启用allowImportingTsExtensions的效果,在不引入后缀名的情况下,效果如下
- // 默认的引入方式,不需要加ts后缀名
- import {a as a1} from './demo1' // tsx
- import {a as a2} from './demo2' // ts
- import {a as a3} from './demo3' // mts
- import {a as a4} from './demo4' // cts
-
- console.log(a1, a2, a3, a4)
tsconfig.json配置如下:
- {
- "compilerOptions": {
- "allowImportingTsExtensions": false,
- "jsx": "preserve" // 开启jsx支持,
- "module": "NodeNext",
- "moduleResolution": "NodeNext"
- }
- }
编译报错如下(引入jsx没有报错):
- ts/index.ts:4:23 - error TS2307: Cannot find module './demo3' or its corresponding type declarations.
-
- 4 import {a as a3} from './demo3'
- ~~~~~~~~~
-
- ts/index.ts:5:23 - error TS2307: Cannot find module './demo4' or its corresponding type declarations.
-
- 5 import {a as a4} from './demo4'
这里需要将demo3和demo4的后缀修改以下(使用 TypeScript 时,您需要使用文件扩展名的JAVASCRIPT版本导入代码。)。这个设定有点奇怪,不过确实typescript永远不会修改你在*.ts中导入的文件后缀和路径。
- // 默认的引入方式,不需要加ts后缀名
- import {a as a1} from './demo1'
- import {a as a2} from './demo2'
- // importing from demo3.mts
- import {a as a3} from './demo3.mjs' // 导入的是*.mts, 使用解析后的js后缀导入
- // importing from demo4.mts
- import {a as a4} from './demo4.cjs' // 导入的是*.cts, 使用解析后的js后缀导入
此时会报错如下:
- ts/index.ts:4:23 - error TS1479: The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("./demo3.mjs")' call instead.
- To convert this file to an ECMAScript module, change its file extension to '.mts' or create a local package.json file with `{ "type": "module" }`.
-
- 4 import {a as a3} from './demo3.mjs'
这是因为我的package.json设置的type类型为commonjs,入口文件index.ts的后缀为*.ts,所以他不能导入ESM模块系统的文件(*.mts/*.mjs),我们将index.ts修改为index.mts,此时会报错:
- ts/index.mts:2:23 - error TS2835: Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean './demo1.jsx'?
-
- 2 import {a as a1} from './demo1'
- ~~~~~~~~~
-
- ts/index.mts:3:23 - error TS2835: Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean './demo2.js'?
-
- 3 import {a as a2} from './demo2'
我们根据提示补全了这两个引入的后缀:
- // 默认的引入方式,不需要加ts后缀名
- import {a as a1} from './demo1.js'
- import {a as a2} from './demo2.jsx'
- import {a as a3} from './demo3.mjs'
- import {a as a4} from './demo4.cjs'
-
- console.log(a1, a2, a3, a4)
此时就不报错了,可以正常编译了。
因为typescript在编译后的js文件中不会对导入模块的地址和文件后缀做任何修改,所以如果开启了allowImportingTsExtensions之后编译的js文件的导入文件后缀仍然是.ts, .mts和 .tsx等,无法被js正常执行。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。