打字稿导出与默认导出


272

export和之间的Typescript有什么区别default export。在所有教程中,我看到人们在写export他们的课程,并且如果我default在导出之前未添加关键字,则无法编译我的代码。

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

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.



3
关于该主题的一些轻松阅读。如果您演示如何导入此类,可能会有所帮助,我相信这就是发生错误的地方(您可能需要更改导入语法以解决错误情况)。
Sunil D. 2015年

5
“ export”和“ export default”根本不是TypeScript,它们是ES6。
Sensei James

Answers:


458

默认导出(export default

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

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

import MyClass from "./MyClass";

您可以给它任何喜欢的名字。例如,这很好用:

import MyClassAlias from "./MyClass";

命名为出口(export

// 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

3
发生了什么事import myAlias = require("./PathToFile"),并具有export = IInterfaceOrClass在该文件中?那是老式的吗?
BenCr

@BenCr是的,这是新的es6方式
David Sherret

您为什么不举一个“命名出口”的例子?
Stato Machino

aws-sdk / clients / sns没有默认导出,当使用来自'/ sns'的import sns访问sns时,我没有导出,但是导入myAlias = require(“ ./ PathToFile”)可以工作。我可以做些更改以从'/ sns'导入sns而不更改源代码吗?
杰森·迪亚斯

如果您未明确输入关键字default,该文件中是否还会有默认导出?如果是这样,有什么规则。
Simon_Weaver

10

我试图解决同样的问题,但发现了一个有趣的建议Basarat阿里赛义德的,打字稿深潜的名气,我们应该避免通用export default的一类声明,而是追加export标签类的声明。导入的类应改为在import模块的命令中列出。

那就是:代替

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

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

export class Foo {
    // ...
}

import {Foo} from './foo'在进口商。

原因是类的重构困难,并且增加了导出工作。Basarat的原始帖子export default可能会导致问题


0

这是简单对象导出的示例。

var MyScreen = {

    /* ... */

    width : function (percent){

        return window.innerWidth / 100 * percent

    }

    height : function (percent){

        return window.innerHeight / 100 * percent

    }


};

export default MyScreen

在主文件中(不需要和不需要创建新实例时使用),并且它不是全局的,只有在需要时才导入它:

import MyScreen from "./module/screen";
console.log( MyScreen.width(100) );
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.