簡體   English   中英

Typescript 導出與默認導出

[英]Typescript export vs. default export

在 Typescript 中exportdefault export什么區別。 在所有教程中,我看到人們export他們的類,如果我在導出之前不添加default關鍵字,我將無法編譯我的代碼。

此外,我在官方打字稿文檔中找不到任何關於默認導出關鍵字的痕跡。

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.

默認出口( 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 *文件——export 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

我試圖解決同樣的問題,但發現了一個由TypeScript Deep Dive著名的 Basarat Ali Syed提出的有趣建議,即我們應該避免類的通用export default聲明,而是將export標記附加到類聲明中。 導入的類應該列在模塊的import命令中。

那就是:而不是

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

和簡單的import Foo from './foo'; 在將導入的模塊中,應該使用

export class Foo {
    // ...
}

並在import {Foo} from './foo'

原因是類重構的困難,以及導出的額外工作。 Basarat 的原始帖子是在export default可能會導致問題

命名導出

在 TS 中,您可以使用export關鍵字export 然后可以通過import {name} from "./mydir";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

模塊及其相關關鍵字(如importexportexport default是 JavaScript 構造,而不是打字稿。 然而,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) );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM