仅类型导入的真实用例是什么,证明增加的冗长是合理的?

Adr*_*uro 17 lint typescript type-only-import-export

当我升级到最新版本的 TypeScript 并发现仅类型导入时,我认为它非常酷并开始在任何地方使用它。

设置仅类型导入一段时间后,我很快意识到我得到了预期的更多冗长和“脏代码”。

没有仅类型导入:

import { SomeType, someFunction, SomeClassToInstantiate } from '@my-app/lib1';
import { OtherType, otherFunction, OtherClassToInstantiate } from '@my-app/lib2';
Run Code Online (Sandbox Code Playgroud)

仅导入类型:

import type { SomeType } from '@my-app/lib1';
import { someFunction, SomeClassToInstantiate } from '@my-app/lib1';
import type { OtherType } from '@my-app/lib2';
import { otherFunction, OtherClassToInstantiate } from '@my-app/lib2';
Run Code Online (Sandbox Code Playgroud)

基本上,我的很多导入都会重复,并且很难跟踪我是否以正确的方式导入所有内容(如果我导入为我在文件中实际使用的类型,则编译器会进行标记 - 但相反的情况则不然)等等,我没有找到任何工具来标记导入仅用作类型并且应该切换到仅类型导入)。

也许我更注意到这个问题,因为我正在使用 NX 并且我的应用程序的很多代码都来自库的桶文件;即,经常发生类型和非类型都必须从同一模块导入的情况。

所以我想知道,在任何地方使用仅类型导入能获得什么实际优势?是否在某些特定情况下使用它肯定有帮助,并且在所有其他情况下都可以绕过它?

如果我上一个问题的答案是应该在可能的情况下始终使用它,那么您是否知道在可以使用类型导入时强制执行类型导入的 linting 规则?

我不喜欢导入量比以前增加近一倍的混乱,甚至不知道它们始终在各地的常规/仅类型导入中划分。

Ole*_*ter 13

\n

是否存在使用它肯定有帮助的特定情况,并且在所有其他情况下可以绕过它?

\n
\n

尽管无条件地使用仅类型导入并没有什么坏处(为了一致性),但确实存在需要它们的特定情况。下表根据用例比较了不同的选项组合:

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
isolatedModules/preserveValueImportstruefalse
true需要仅类型导入,因为单文件处理缺乏完整的类型系统信息来消除类型导入。
例子
如果导出类型,则需要仅导出类型。
例子
false优惠的、仅限类型的导入将被取消优惠的、仅限类型的导入将被取消
\n
\n

它们最常见的用例是同时启用isolatedModules和时,这是明确记录的preserveValueImports

\n
\n

与isolatedModules结合使用时:导入的类型必须标记为仅类型,因为一次处理单个文件的编译器无法知道导入是否是未使用的值,或者是必须删除以避免运行时崩溃的类型。

\n
\n

另一个用例是isolatedModules启用模块时(无论preserveValueImports选项如何),并且您正在导出类型(导入或未导入),这也有记录

\n
\n

单文件转译器不知道 someType 是否生成值,因此导出仅引用类型的名称是错误的。

\n
\n

如果您的配置已preserveValueImports启用,则仅类型导入对于强制省略仅在类型位置中使用的导入也很有用,如果保留这些导入,则不会出现运行时错误(在下面的示例中,将允许import type编译器完全省略导入):

\n
import { ESLint } from "eslint"; // ESLint is a class\nlet esl: ESLint;\nexport { esl };\n
Run Code Online (Sandbox Code Playgroud)\n
\n

至于 linting,@typescript-eslint/eslint-pluginESLint 有 2 条规则来管理仅类型导入和导出的使用:

\n\n
\n

值得注意的是,从 4.5 开始,TypeScript在导入名称上添加了类型修饰符,这些修饰符是专门为解决仅类型导入的冗长问题而添加的,因此您不再需要拆分导入:

\n
import { someFunction, SomeClassToInstantiate, type SomeType } from \'@my-app/lib1\';\n
Run Code Online (Sandbox Code Playgroud)\n

  • 感谢您提到“import { type SomeType, someFunction, SomeClass }”打字稿语法,以便更简洁地导入。 (3认同)
  • @tinystone NP :) 值得庆幸的是,TS 团队听取了请求并在 4.5 中添加了此选项 - 事实上,必须编写两次模块说明符才能使用仅类型导入,这确实非常冗长。 (3认同)