是
import type { Foo, Bar as Baz } from './'
Run Code Online (Sandbox Code Playgroud)
和
type Foo = import('./').Foo
type Bar = import('./').Baz
Run Code Online (Sandbox Code Playgroud)
相等的?
请注意,import()这里的 不是动态导入,而是TypeScript 2.9 中引入的import类型。您可以将这两个示例输入TypeScript Playground以验证语法/类型是否有效。
我想使用import type但也创建 TS < 3.8 的声明。
如果上述断言成立,我可以将 AST 转换应用于发出的声明文件。
And*_*rew 12
尽管它们在实践中经常可以互换,但它们并不等同。根据具体情况,有两个差异可能很重要。
\nimport type使文件成为模块。TypeScript 编译器通过是否存在任何 或 声明来确定 TypeScript 文件\xe2\x80\x99s 顶级作用域是模块作用域还是全局作用域(即文件是模块还是脚本import)export。import type算作导入声明,因此如果它是文件中唯一的导入/导出语句,则用类型别名替换它会将文件从模块更改为脚本。这样做的实际含义是,如果您有一个需要全局的文件(通常是 .d.ts 文件),但想要引用模块中的类型,则\xe2\x80\x99 会陷入困境type Foo = import(...).
import type可以引用值和命名空间的含义。当您使用 声明类型别名时type Foo = import(\'./\').Bar,纯粹Foo是一种类型,即使同时具有类型和值含义(例如)。您在此声明中完全忽略了价值方面。实际上引用了完整的Barclass Bar {}Barimport typeBar符号及其所有含义,它只是设置了一个语法检查,确保您永远不会在会发送到 JS 的位置使用它(因为 import 语句将在 JS 中被删除)。这在几个地方很重要,最容易用一个例子来展示:
import type { EventEmitter as EE1 } from "events";\ntype EE2 = import("events").EventEmitter;\n\n// Ok, because `declare` means `Foo1` is not actually referenced\n// in an emitting position.\ndeclare class Derived1 extends EE1 {}\n\ndeclare class Derived2 extends EE2 {}\n// ^^^\n// Error: \'EE2\' only refers to a type, but is being used as a value here.\n\ntype EventEmitterCtor1 = typeof EE1; // Ok\ntype EventEmitterCtor2 = typeof EE2;\n// ^^^\n// Error: \'EE2\' only refers to a type, but is being used as a value here.\n\nconst x = EE1;\n// ^^^\n// Error: \'EE1\' cannot be used as a value because it was imported using \'import type\'\n\nconst y = EE2;\n// ^^^\n// \'EE2\' only refers to a type, but is being used as a value here.\nRun Code Online (Sandbox Code Playgroud)\n\n
| 归档时间: |
|
| 查看次数: |
7193 次 |
| 最近记录: |