首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >` `import type`是否等同于` `import()`

` `import type`是否等同于` `import()`
EN

Stack Overflow用户
提问于 2021-03-27 18:04:30
回答 1查看 170关注 0票数 2

代码语言:javascript
复制
import type { Foo, Bar as Baz } from './'

代码语言:javascript
复制
type Foo = import('./').Foo
type Bar = import('./').Baz

等价物?

请注意,此上下文中的import()不是动态导入,而是TypeScript 2.9中引入的import types。您可以在TypeScript playground中输入这两个示例,以验证语法/类型是否有效。

我想使用import type,但也要为TS < 3.8创建声明。

如果上面的断言是真的,我可以对发出的声明文件应用AST转换。

EN

回答 1

Stack Overflow用户

发布于 2021-03-28 00:12:00

它们不是等价的,尽管它们在实践中经常是可以互换的。根据上下文的不同,有两个差异可能很重要。

import type使文件成为一个模块。

TypeScript编译器通过存在任何importexport声明来确定TypeScript文件的顶级作用域是模块作用域还是全局作用域(即文件是模块还是脚本)。import type算作导入声明,因此如果它是文件中唯一的导入/导出语句,则用类型别名替换它会将文件从模块更改为脚本。这一点的实际含义是,如果有一个文件(通常是.d.ts文件)需要是全局的,但又想引用模块中的类型,那么就只能使用type Foo = import(...)

import type可以引用值和名称空间含义。

当您使用type Foo = import('./').Bar声明类型别名时,Foo纯粹是一个类型,即使Bar同时具有类型和值含义(例如class Bar {})。在此声明中,您完全忽略了Bar的值方面。import type实际上引用了完整的导入符号及其所有含义,它只是设置了一个语法检查,以确保您永远不会在会向JS发出的位置使用它(因为Bar语句将在JS中被擦除)。这在几个地方很重要,最容易用一个例子来说明:

代码语言:javascript
复制
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.

(Playground link)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66830081

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档