今天在看ant-design-vue
源码的时候发现在代码中大量使用了import
和import type
,于是我就比较好奇他们到底有什么不同,但是查看了TypeScript
手册,可能是比较基础的知识,并未对其进行解说。最终,经过我的不懈了解,终于了解这两种的区别。
如上,查看代码发现,通过import type
导入的其本身也是通过export type
导出的。
当我们通过import type
导出后使用,如下:
// a.ts
export enum MyEnum {
DEFAULT = 0,
SOME_VALUE = 1,
SOME_OTHER_VALUE = 2,
}
//b.ts
import type { MyEnum } from './b';
const someFunction = (myEnum: MyEnum) => {
if (myEnum === MyEnum.SOME_VALUE) {
// some logic here
return
}
if (myEnum === MyEnum.SOME_OTHER_VALUE) {
// some logic here
return
}
// some logic here
return
}
这时编译器突然报错:
'MyEnum' cannot be used as a value because it was imported using 'import type'.ts(1361)
字面意思就是MyEnum
是通过import type
导出的,所以不能作为一个正常的值来使用。那么,问题来了,我们应该什么时候使用import type
呢?
依据
通过反复查阅资料发现这时TypeScript 3.8新增的功能,其原文如下:
i
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.htmlmport type
only imports declarations to be used for type annotations and declarations. It always gets fully erased, so there’s no remnant of it at runtime. Similarly,export type
only provides an export that can be used for type contexts, and is also erased from TypeScript’s output.
大概意思就是import type是TypeScript 3.8新增的一种用于仅类型的导入和导出的语法。它在运行时是完全不存在的。主要是辅助我们做类型校验的。
总结
通过上述的了解,总结其特点如下:
import type
仅仅引入类型信息,不会引入实际的对象,而import
会引入实际的 JavaScript 对象。- 使用
import type
时,无法使用导入的类型作为值进行实例化或传递给函数。 import type
只用于导入类型声明,例如接口、类型别名、枚举等。而import
可以用于导入值、函数、类等任何东西。
// foo.ts
export interface Foo {
bar: string;
}
// index.ts
import { Foo } from './foo'; // 这里导入了实际的 Foo 接口对象
import type { Foo as FooType } from './foo'; // 这里导入了 Foo 接口的类型信息
const foo: Foo = { bar: 'baz' }; // 正常使用 Foo 接口对象
const fooType: FooType = { bar: 'baz' }; // 无法使用 Foo 接口的类型信息创建一个对象,TypeScript3.8以前的版本这里会报错。3.8之后的版本就不会报错了
当我们只需要类型信息时,应该使用 import type
。这样可以避免引入多余的代码,并提高编译性能。而当你需要实际的 JavaScript
对象时,则需要使用 import
。