类型脚本导出与默认导出

2022-08-29 23:34:53

在 Typescript 中,和 有什么区别。在所有教程中,我看到人们在他们的类中,如果我在导出之前不添加关键字,我就无法编译我的代码。exportdefault exportexportdefault

另外,我在官方typescript文档中找不到默认导出关键字的任何痕迹。

export class MyClass {

  collection = [1,2,3];

}

不编译。但:

export default class MyClass {

  collection = [1,2,3];

}

确实如此。

错误是:error TS1192: Module '"src/app/MyClass"' has no default export.


答案 1

默认导出(导出默认值

// MyClass.ts -- using default export
export default class MyClass { /* ... */ }

主要区别在于,每个文件只能有一个默认导出,并且像这样导入它:

import MyClass from "./MyClass";

你可以给它任何你喜欢的名字。例如,这工作正常:

import MyClassAlias from "./MyClass";

命名导出(导出

// MyClass.ts -- using named exports
export class MyClass { /* ... */ }
export class MyOtherClass { /* ... */ }

使用命名导出时,可以对每个文件进行多次导出,并且需要导入括在大括号中的导出:

import { MyClass } from "./MyClass";

注意:添加大括号将修复您在问题中描述的错误,并且大括号中指定的名称需要与导出的名称匹配。

或者假设您的文件导出了多个类,然后您可以像这样导入这两个类:

import { MyClass, MyOtherClass } from "./MyClass";
// use MyClass and MyOtherClass

或者,您可以在此文件中为它们中的任何一个指定一个不同的名称:

import { MyClass, MyOtherClass as MyOtherClassAlias } from "./MyClass";
// use MyClass and MyOtherClassAlias

或者,您可以使用以下命令导入导出的所有内容:* as

import * as MyClasses from "./MyClass";
// use MyClasses.MyClass and MyClasses.MyOtherClass here

使用哪个?

在ES6中,默认导出是简洁的,因为它们的用例更常见;但是,当我在TypeScript中处理项目内部的代码时,我更喜欢使用命名导出而不是默认导出,因为它非常适合代码重构。例如,如果默认导出某个类并重命名该类,则它只会重命名该文件中的类,而不会重命名其他文件中的任何其他引用。使用命名导出,它将重命名该类以及所有其他文件中对该类的所有引用。

它也非常适合桶形文件(使用命名空间导出的文件 - 导出其他文件)。本答案的“示例”部分显示了此示例。export *

请注意,我对使用命名导出(即使只有一个导出)的看法与 TypeScript 手册相反 — 请参阅“危险信号”部分。我相信这个建议只适用于你创建一个供其他人使用的API,并且代码不是你的项目内部的。当我设计一个供人们使用的API时,我将使用默认导出,以便人们可以这样做。如果你不同意我这样做,我很想听听你的理由。import myLibraryDefaultExport from "my-library-name";

也就是说,找到你喜欢的东西!您可以同时使用一个,另一个或两者。

额外积分

默认导出实际上是名为 的命名导出,因此,如果文件具有默认导出,则还可以通过执行以下操作进行导入:default

import { default as MyClass } from "./MyClass";

请注意存在以下其他导入方式

import MyDefaultExportedClass, { Class1, Class2 } from "./SomeFile";
import MyDefaultExportedClass, * as Classes from "./SomeFile";
import "./SomeFile"; // runs SomeFile.js without importing any exports

答案 2

我试图解决同样的问题,但发现了Basarat Ali Syed的一个有趣的建议,TypeScript Deep Dive的名声,我们应该避免类的泛型声明,而是将标签附加到类声明中。导入的类应改为在模块的命令中列出。export defaultexportimport

即:而不是

class Foo {
    // ...
}
export default Foo;

和将导入的模块中的简单,应该使用import Foo from './foo';

export class Foo {
    // ...
}

和导入器中。import {Foo} from './foo'

其原因是类重构的困难,以及导出的附加工作。Basarat的原始帖子位于“避免导出默认值”