是
import type { Foo, Bar as Baz } from './'和
type Foo = import('./').Foo
type Bar = import('./').Baz等价物?
请注意,此上下文中的import()不是动态导入,而是TypeScript 2.9中引入的import types。您可以在TypeScript playground中输入这两个示例,以验证语法/类型是否有效。
我想使用import type,但也要为TS < 3.8创建声明。
如果上面的断言是真的,我可以对发出的声明文件应用AST转换。
发布于 2021-03-28 00:12:00
它们不是等价的,尽管它们在实践中经常是可以互换的。根据上下文的不同,有两个差异可能很重要。
import type使文件成为一个模块。
TypeScript编译器通过存在任何import或export声明来确定TypeScript文件的顶级作用域是模块作用域还是全局作用域(即文件是模块还是脚本)。import type算作导入声明,因此如果它是文件中唯一的导入/导出语句,则用类型别名替换它会将文件从模块更改为脚本。这一点的实际含义是,如果有一个文件(通常是.d.ts文件)需要是全局的,但又想引用模块中的类型,那么就只能使用type Foo = import(...)。
import type可以引用值和名称空间含义。
当您使用type Foo = import('./').Bar声明类型别名时,Foo纯粹是一个类型,即使Bar同时具有类型和值含义(例如class Bar {})。在此声明中,您完全忽略了Bar的值方面。import type实际上引用了完整的导入符号及其所有含义,它只是设置了一个语法检查,以确保您永远不会在会向JS发出的位置使用它(因为Bar语句将在JS中被擦除)。这在几个地方很重要,最容易用一个例子来说明:
import type { EventEmitter as EE1 } from "events";
type EE2 = import("events").EventEmitter;
// Ok, because `declare` means `Foo1` is not actually referenced
// in an emitting position.
declare class Derived1 extends EE1 {}
declare class Derived2 extends EE2 {}
// ^^^
// Error: 'EE2' only refers to a type, but is being used as a value here.
type EventEmitterCtor1 = typeof EE1; // Ok
type EventEmitterCtor2 = typeof EE2;
// ^^^
// Error: 'EE2' only refers to a type, but is being used as a value here.
const x = EE1;
// ^^^
// Error: 'EE1' cannot be used as a value because it was imported using 'import type'
const y = EE2;
// ^^^
// 'EE2' only refers to a type, but is being used as a value here.https://stackoverflow.com/questions/66830081
复制相似问题