Typescript 导出与默认导出
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33305954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Typescript export vs. default export
提问by fos.alex
What is the difference in Typescript between export
and default export
. In all the tutorials I see people export
ing their classes and I cannot compile my code if I don't add the default
keyword before exporting.
Typescriptexport
和default export
. 在所有教程中,我看到有人在使用export
他们的类,如果default
在导出之前不添加关键字,我将无法编译我的代码。
Also, I couldn't find any trace of the default export keyword in the official typescript documentation.
此外,我在官方打字稿文档中找不到任何关于默认导出关键字的痕迹。
export class MyClass {
collection = [1,2,3];
}
Does not compile. But:
不编译。但:
export default class MyClass {
collection = [1,2,3];
}
Does.
做。
The error is: error TS1192: Module '"src/app/MyClass"' has no default export.
错误是: error TS1192: Module '"src/app/MyClass"' has no default export.
回答by David Sherret
Default Export (export default
)
默认导出 ( export default
)
// MyClass.ts -- using default export
export default class MyClass { /* ... */ }
The main difference is that you can only have one default export per file and you import it like so:
主要区别在于每个文件只能有一个默认导出,您可以像这样导入它:
import MyClass from "./MyClass";
You can give it any name you like. For example this works fine:
你可以给它任何你喜欢的名字。例如这工作正常:
import MyClassAlias from "./MyClass";
Named Export (export
)
命名导出 ( export
)
// MyClass.ts -- using named exports
export class MyClass { /* ... */ }
export class MyOtherClass { /* ... */ }
When you use a named export, you can have multiple exports per file and you need to import the exports surrounded in braces:
使用命名导出时,每个文件可以有多个导出,并且需要导入括在大括号中的导出:
import { MyClass } from "./MyClass";
Note: Adding the braces will fix the error you're describing in your question and the name specified in the braces needs to match the name of the export.
注意:添加大括号将修复您在问题中描述的错误,并且大括号中指定的名称需要与导出的名称相匹配。
Or say your file exported multipleclasses, then you could import both like so:
或者说您的文件导出了多个类,然后您可以像这样导入两个类:
import { MyClass, MyOtherClass } from "./MyClass";
// use MyClass and MyOtherClass
Or you could give either of them a different name in this file:
或者您可以在此文件中为其中任何一个指定不同的名称:
import { MyClass, MyOtherClass as MyOtherClassAlias } from "./MyClass";
// use MyClass and MyOtherClassAlias
Or you could import everything that's exported by using * as
:
或者您可以使用以下命令导入导出的所有内容* as
:
import * as MyClasses from "./MyClass";
// use MyClasses.MyClass and MyClasses.MyOtherClass here
Which to use?
使用哪个?
In ES6, default exports are concise because their use case is more common; however, when I am working on code internal to a project in TypeScript, I prefer to use named exports instead of default exports almost all the time because it works very well with code refactoring. For example, if you default export a class and rename that class, it will only rename the class in that file and not any of the other references in other files. With named exports it will rename the class and all the references to that class in all the other files.
在 ES6 中,默认导出是简洁的,因为它们的用例更常见;然而,当我在 TypeScript 中处理项目内部的代码时,我几乎一直都喜欢使用命名导出而不是默认导出,因为它与代码重构配合得很好。例如,如果您默认导出一个类并重命名该类,它只会重命名该文件中的类,而不会重命名其他文件中的任何其他引用。使用命名导出,它将重命名类以及所有其他文件中对该类的所有引用。
It also plays very nicely with barrel files(files that use namespace exports—export *
—to export other files). An example of this is shown in the "example" section of this answer.
它还可以很好地处理桶文件(使用命名空间export *
导出的文件——导出其他文件)。此答案的“示例”部分显示了一个示例。
Note that my opinion on using named exports even when there is only one export is contrary to the TypeScript Handbook—see the "Red Flags" section. I believe this recommendation only applies when you are creating an API for other people to use and the code is not internal to your project. When I'm designing an API for people to use, I'll use a default export so people can do import myLibraryDefaultExport from "my-library-name";
. If you disagree with me about doing this, I would love to hear your reasoning.
请注意,即使只有一个导出,我对使用命名导出的看法也与TypeScript 手册相反——请参阅“红旗”部分。我相信此建议仅适用于您正在创建供其他人使用的 API 并且代码不在您的项目内部的情况下。当我设计一个供人们使用的 API 时,我将使用默认导出,以便人们可以执行import myLibraryDefaultExport from "my-library-name";
. 如果你不同意我这样做,我很想听听你的推理。
That said, find what you prefer! You could use one, the other, or both at the same time.
也就是说,找到你喜欢的!您可以同时使用一个、另一个或两者。
Additional Points
附加分
A default export is actually a named export with the name default
, so if the file has a default export then you can also import by doing:
默认导出实际上是具有 name 的命名导出default
,因此如果文件具有默认导出,那么您也可以通过执行以下操作导入:
import { default as MyClass } from "./MyClass";
And take note these other waysto import exist:
import MyDefaultExportedClass, { Class1, Class2 } from "./SomeFile";
import MyDefaultExportedClass, * as Classes from "./SomeFile";
import "./SomeFile"; // runs SomeFile.js without importing any exports
回答by Hilton Fernandes
I was trying to solve the same problem, but found an interesting advice by Basarat Ali Syed, of TypeScript Deep Divefame, that we should avoid the generic export default
declaration for a class, and instead append the export
tag to the class declaration. The imported class should be instead listed in the import
command of the module.
我试图解决同样的问题,但发现了一个有趣的建议Basarat阿里赛义德的,打字稿深潜的名气,我们应该避免通用export default
的一类声明,而是追加export
标签类的声明。导入的类应该列在import
模块的命令中。
That is: instead of
那就是:而不是
class Foo {
// ...
}
export default Foo;
and the simple import Foo from './foo';
in the module that will import, one should use
以及import Foo from './foo';
将导入的模块中的简单内容,应该使用
export class Foo {
// ...
}
and import {Foo} from './foo'
in the importer.
并import {Foo} from './foo'
在进口商。
The reason for that is difficulties in the refactoring of classes, and the added work for exportation. The original post by Basarat is in export default
can lead to problems
原因是类重构的困难,以及导出的额外工作。Basarat 的原帖export default
可能会导致问题
回答by Nikola Lukic
Here's example with simple object exporting.
这是简单对象导出的示例。
var MyScreen = {
/* ... */
width : function (percent){
return window.innerWidth / 100 * percent
}
height : function (percent){
return window.innerHeight / 100 * percent
}
};
export default MyScreen
In main file (Use when you don't want and don't need to create new instance) and it is not global you will import this only when it needed :
在主文件中(当您不需要并且不需要创建新实例时使用)并且它不是全局的,您只会在需要时导入它:
import MyScreen from "./module/screen";
console.log( MyScreen.width(100) );