Typescript 导出与默认导出

IT技术 javascript typescript ecmascript-6
2021-01-25 22:25:18

是什么之间的typescript的差异exportdefault export在所有教程中,我看到有人在使用export他们的类,如果default在导出之前不添加关键字,我将无法编译我的代码

此外,我在官方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.

4个回答

默认导出 ( 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";. 如果你不同意我这样做,我很想听听你的推理。

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

附加分

默认导出实际上是具有 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
发生了什么事import myAlias = require("./PathToFile"),并具有export = IInterfaceOrClass在该文件中?现在是老式了吗?
2021-03-16 22:25:18
aws-sdk/clients/sns 没有默认导出,当使用 import sns from '/sns' 访问 sns 时,我没有导出,但 import myAlias = require("./PathToFile") 有效。我可以做些什么来改变它从'/ sns'导入sns而不进行源更改吗?
2021-03-26 22:25:18
如果您没有明确放置关键字default,该文件中还会有默认导出吗?如果是这样,规则是什么。
2021-03-26 22:25:18
你为什么不举一个“命名导出”的例子?
2021-04-05 22:25:18
@BenCr 是的,这是新的 es6 方式
2021-04-06 22:25:18

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

那就是:而不是

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

以及import Foo from './foo';将导入的module中的简单内容,应该使用

export class Foo {
    // ...
}

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

原因是类重构的困难,以及导出的额外工作。Basarat 的原帖export default可能会导致问题

命名导出

在 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";

以下替代语法也有效:

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

// main.js file in same dir
import {foo, bar} from './foo'

默认导出

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

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

// main.js file in same directory
import abc from "./foo";

这只是 JavaScript

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

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

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) );