打字稿导出与默认导出

fos*_*lex 227 typescript ecmascript-6

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

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

export class MyClass {

  collection = [1,2,3];

}
Run Code Online (Sandbox Code Playgroud)

不编译.但:

export default class MyClass {

  collection = [1,2,3];

}
Run Code Online (Sandbox Code Playgroud)

请问.

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

Dav*_*ret 407

默认导出(export default)

// MyClass.ts -- using default export
export default class MyClass { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

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

import MyClass from "./MyClass";
Run Code Online (Sandbox Code Playgroud)

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

import MyClassAlias from "./MyClass";
Run Code Online (Sandbox Code Playgroud)

命名导出(export)

// MyClass.ts -- using named exports
export class MyClass { /* ... */ }
export class MyOtherClass { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

使用命名导出时,每个文件可以有多个导出,并且需要导入括号中包含的导出:

import { MyClass } from "./MyClass";
Run Code Online (Sandbox Code Playgroud)

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

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

import { MyClass, MyOtherClass } from "./MyClass";
// use MyClass and MyOtherClass
Run Code Online (Sandbox Code Playgroud)

或者您可以在此文件中为其中任何一个指定其他名称:

import { MyClass, MyOtherClass as MyOtherClassAlias } from "./MyClass";
// use MyClass and MyOtherClassAlias
Run Code Online (Sandbox Code Playgroud)

或者您可以使用以下方法导入导出的所有内容* as:

import * as MyClasses from "./MyClass";
// use MyClasses.MyClass and MyClasses.MyOtherClass here
Run Code Online (Sandbox Code Playgroud)

哪个用?

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

它还可以很好地处理桶文件(使用命名空间export *导出的文件 - 导出其他文件).此答案的"示例"部分中显示了此示例.

请注意,即使只有一个导出,我对使用命名导出的看法与TypeScript手册相反- 请参阅"Red Flags"部分.我相信此建议仅适用于您为其他人创建API以及代码不在您的项目内部时.当我为人们设计API时,我将使用默认导出,以便人们可以做到import myLibraryDefaultExport from "my-library-name";.如果你不同意我这样做,我很乐意听你的推理.

那说,找到你喜欢的!您可以同时使用一个,另一个或两者.

附加点

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

import { default as MyClass } from "./MyClass";
Run Code Online (Sandbox Code Playgroud)

并注意这些导入的其他方式存在: 

import MyDefaultExportedClass, { Class1, Class2 } from "./SomeFile";
import MyDefaultExportedClass, * as Classes from "./SomeFile";
import "./SomeFile"; // runs SomeFile.js without importing any exports
Run Code Online (Sandbox Code Playgroud)

  • `import myAlias = require(“ ./ PathToFile”)`并在文件中具有`export = IInterfaceOrClass`是怎么回事?那是老式的吗? (2认同)

小智 5

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

那就是:代替

class Foo {
    // ...
}
export default Foo;
Run Code Online (Sandbox Code Playgroud)

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

export class Foo {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

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

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


Wil*_*een 5

命名导出

在 TS 中,您可以使用export关键字导出。然后可以通过import {name} from "./mydir";. 这称为命名导出。一个文件可以导出多个命名导出。此外,进口的名称必须与出口相匹配。例如:

// foo.js file
export class foo{}
export class bar{}

// main.js file in same dir
import {foo, bar} from "./foo";
Run Code Online (Sandbox Code Playgroud)

以下替代语法也有效:

// foo.js file
function foo() {};
function bar() {};
export {foo, bar};

// main.js file in same dir
import {foo, bar} from './foo'
Run Code Online (Sandbox Code Playgroud)

默认导出

我们也可以使用默认的 export。每个文件只能有一个默认导出。导入默认导出时,我们省略了 import 语句中的方括号。我们也可以为我们的导入选择我们自己的名称。

// foo.js file
export default class foo{}

// main.js file in same directory
import abc from "./foo";
Run Code Online (Sandbox Code Playgroud)

这只是 JavaScript

模块及其相关关键字如importexportexport default是 JavaScript 结构,而不是打字稿。然而,typescript 添加了接口和类型别名的导出和导入。