当前位置:   article > 正文

Typescript配置文件(tsconfig.json)详解系列六:allowImportingTsExtensions_tsconfig import带json

tsconfig import带json

前言

本文使用的Typescript版本为5.5.2

配置

  1. {
  2. compilerOptions: {
  3. "allowImportingTsExtensions": true
  4. }
  5. }

说明

allowImportingTsExtensionstypescript@5.x后加入的字段。

配置启用后,import其他模块时允许携带.ts.mts和 .tsx等typescript支持的扩展名

  1. // 默认的引入方式,不需要加ts后缀名
  2. import {a as a1} from './demo2'
  3. import {a as a2} from './demo2.ts'
  4. import {a as a3} from './demo1.tsx'
  5. import {a as a4} from './demo3.mts'
  6. import {a as a5} from './demo4.cts'
  7. export {a1, a2, a3, a4, a5}

不开启的时候会报错如下:

  1. ts/index.ts:4:23 - error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.
  2. 4 import {a as a2} from './demo2.ts'
  3. ~~~~~~~~~~~~
  4. ts/index.ts:5:23 - error TS5097: An import path can only end with a '.tsx' extension when 'allowImportingTsExtensions' is enabled.
  5. 5 import {a as a3} from './demo1.tsx'
  6. ~~~~~~~~~~~~~
  7. ts/index.ts:6:23 - error TS5097: An import path can only end with a '.mts' extension when 'allowImportingTsExtensions' is enabled.
  8. 6 import {a as a4} from './demo3.mts'
  9. ~~~~~~~~~~~~~
  10. ts/index.ts:7:23 - error TS5097: An import path can only end with a '.cts' extension when 'allowImportingTsExtensions' is enabled.
  11. 7 import {a as a5} from './demo4.cts'
  12. ~~~~~~~~~~~~~

此标志仅在启用 --noEmit(不输出编译后的js文件)--emitDeclarationOnly(只编译输出类型声明文件d.ts) 时才允许。

编译后为*.d.ts(--emitDeclarationOnly),编译后的结果如下(看起来文件后缀名还会被保留):

  1. import { a as a1 } from './demo2';
  2. import { a as a2 } from './demo2.ts';
  3. import { a as a3 } from './demo1.tsx';
  4. import { a as a4 } from './demo3.mts';
  5. import { a as a5 } from './demo4.cts';
  6. export { a1, a2, a3, a4, a5 };

后记

我们来看看不启用allowImportingTsExtensions的效果,在不引入后缀名的情况下,效果如下

  1. // 默认的引入方式,不需要加ts后缀名
  2. import {a as a1} from './demo1' // tsx
  3. import {a as a2} from './demo2' // ts
  4. import {a as a3} from './demo3' // mts
  5. import {a as a4} from './demo4' // cts
  6. console.log(a1, a2, a3, a4)

tsconfig.json配置如下:

  1. {
  2. "compilerOptions": {
  3. "allowImportingTsExtensions": false,
  4. "jsx": "preserve" // 开启jsx支持,
  5. "module": "NodeNext",
  6. "moduleResolution": "NodeNext"
  7. }
  8. }

 编译报错如下(引入jsx没有报错):

  1. ts/index.ts:4:23 - error TS2307: Cannot find module './demo3' or its corresponding type declarations.
  2. 4 import {a as a3} from './demo3'
  3. ~~~~~~~~~
  4. ts/index.ts:5:23 - error TS2307: Cannot find module './demo4' or its corresponding type declarations.
  5. 5 import {a as a4} from './demo4'

 这里需要将demo3和demo4的后缀修改以下(使用 TypeScript 时,您需要使用文件扩展名的JAVASCRIPT版本导入代码。)。这个设定有点奇怪,不过确实typescript永远不会修改你在*.ts中导入的文件后缀和路径。

  1. // 默认的引入方式,不需要加ts后缀名
  2. import {a as a1} from './demo1'
  3. import {a as a2} from './demo2'
  4. // importing from demo3.mts
  5. import {a as a3} from './demo3.mjs' // 导入的是*.mts, 使用解析后的js后缀导入
  6. // importing from demo4.mts
  7. import {a as a4} from './demo4.cjs' // 导入的是*.cts, 使用解析后的js后缀导入

此时会报错如下:

  1. 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.
  2. To convert this file to an ECMAScript module, change its file extension to '.mts' or create a local package.json file with `{ "type": "module" }`.
  3. 4 import {a as a3} from './demo3.mjs'

这是因为我的package.json设置的type类型为commonjs,入口文件index.ts的后缀为*.ts,所以他不能导入ESM模块系统的文件(*.mts/*.mjs),我们将index.ts修改为index.mts,此时会报错:

  1. 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. 2 import {a as a1} from './demo1'
  3. ~~~~~~~~~
  4. 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'?
  5. 3 import {a as a2} from './demo2'

我们根据提示补全了这两个引入的后缀:

  1. // 默认的引入方式,不需要加ts后缀名
  2. import {a as a1} from './demo1.js'
  3. import {a as a2} from './demo2.jsx'
  4. import {a as a3} from './demo3.mjs'
  5. import {a as a4} from './demo4.cjs'
  6. console.log(a1, a2, a3, a4)

此时就不报错了,可以正常编译了。

总结

  • 如果不使用allowImportingTsExtensions的时候,在导入文件的时候需要加上typescript编译后的文件后缀。
  • 如果使用了allowImportingTsExtensions就不能输出编译文件,只能输出声明文件(*.d.ts)。

原因分析:

因为typescript在编译后的js文件中不会对导入模块的地址和文件后缀做任何修改,所以如果开启了allowImportingTsExtensions之后编译的js文件的导入文件后缀仍然是.ts, .mts和 .tsx等,无法被js正常执行。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/956152
推荐阅读
相关标签
  

闽ICP备14008679号