Xuất bản in so với xuất mặc định


273

Sự khác biệt trong Bản đánh máy giữa exportdefault export . Trong tất cả các hướng dẫn, tôi thấy mọi người sử dụng exportcác lớp của họ và tôi không thể biên dịch mã của mình nếu tôi không thêm defaulttừ khóa trước khi xuất.

Ngoài ra, tôi không thể tìm thấy bất kỳ dấu vết nào của từ khóa xuất mặc định trong tài liệu bản thảo chính thức .

export class MyClass {

  collection = [1,2,3];

}

Không biên dịch. Nhưng:

export default class MyClass {

  collection = [1,2,3];

}

Làm.

Lỗi là: error TS1192: Module '"src/app/MyClass"' has no default export.


Điều này có thể giúp: stackoverflow.com/q / 3236163/218196
Felix Kling

3
Một số đọc nhẹ về chủ đề này. Nó có thể hữu ích nếu bạn chỉ ra cách bạn nhập lớp này, tôi tin rằng đó là nơi xảy ra lỗi (có lẽ bạn cần thay đổi cú pháp nhập để sửa kịch bản lỗi).
Sunil D.

5
"xuất" và "xuất mặc định" hoàn toàn không phải là TypeScript - chúng là ES6.
Sensei James

Câu trả lời:


459

Xuất mặc định ( export default)

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

Sự khác biệt chính là bạn chỉ có thể có một lần xuất mặc định cho mỗi tệp và bạn nhập nó như vậy:

import MyClass from "./MyClass";

Bạn có thể đặt cho nó bất kỳ tên nào bạn thích. Ví dụ, điều này hoạt động tốt:

import MyClassAlias from "./MyClass";

Xuất khẩu có tên ( export)

// MyClass.ts -- using named exports
export class MyClass { /* ... */ }
export class MyOtherClass { /* ... */ }

Khi bạn sử dụng xuất khẩu có tên, bạn có thể có nhiều lần xuất cho mỗi tệp và bạn cần nhập xuất khẩu được bao quanh trong dấu ngoặc nhọn:

import { MyClass } from "./MyClass";

Lưu ý: Thêm dấu ngoặc nhọn sẽ khắc phục lỗi bạn mô tả trong câu hỏi của bạn và tên được chỉ định trong dấu ngoặc cần khớp với tên của bản xuất.

Hoặc giả sử tệp của bạn đã xuất nhiều lớp, sau đó bạn có thể nhập cả hai như vậy:

import { MyClass, MyOtherClass } from "./MyClass";
// use MyClass and MyOtherClass

Hoặc bạn có thể đặt cho họ một tên khác trong tệp này:

import { MyClass, MyOtherClass as MyOtherClassAlias } from "./MyClass";
// use MyClass and MyOtherClassAlias

Hoặc bạn có thể nhập mọi thứ được xuất bằng cách sử dụng * as:

import * as MyClasses from "./MyClass";
// use MyClasses.MyClass and MyClasses.MyOtherClass here

Dùng loại nào?

Trong ES6, xuất khẩu mặc định là ngắn gọn vì trường hợp sử dụng của chúng là phổ biến hơn ; tuy nhiên, khi tôi đang làm việc về mã nội bộ cho một dự án trong TypeScript, tôi thích sử dụng xuất khẩu có tên thay vì xuất khẩu mặc định gần như mọi lúc vì nó hoạt động rất tốt với tái cấu trúc mã. Ví dụ: nếu bạn mặc định xuất một lớp và đổi tên lớp đó, nó sẽ chỉ đổi tên lớp trong tệp đó chứ không phải bất kỳ tham chiếu nào khác trong các tệp khác. Với xuất khẩu có tên, nó sẽ đổi tên lớp và tất cả các tham chiếu đến lớp đó trong tất cả các tệp khác.

Nó cũng chơi rất độc đáo với các tệp thùng (các tệp sử dụng không gian tên export *xuất xuất xuất thể. Khác để xuất các tệp khác). Một ví dụ về điều này được hiển thị trong phần "ví dụ" của câu trả lời này .

Lưu ý rằng ý kiến ​​của tôi về việc sử dụng xuất khẩu có tên ngay cả khi chỉ có một lần xuất là trái với Sổ tay TypeScript, xem phần "Cờ đỏ". Tôi tin rằng đề xuất này chỉ áp dụng khi bạn đang tạo API cho người khác sử dụng và mã không nằm trong dự án của bạn. Khi tôi thiết kế API để mọi người sử dụng, tôi sẽ sử dụng xuất mặc định để mọi người có thể làm import myLibraryDefaultExport from "my-library-name";. Nếu bạn không đồng ý với tôi về việc này, tôi rất thích nghe lý lẽ của bạn.

Điều đó nói rằng, tìm thấy những gì bạn thích! Bạn có thể sử dụng cái này, cái kia hoặc cả hai cùng một lúc.

Điểm bổ sung

Xuất mặc định thực sự là xuất có tên với tên default, vì vậy nếu tệp có xuất mặc định thì bạn cũng có thể nhập bằng cách thực hiện:

import { default as MyClass } from "./MyClass";

Và lưu ý những cách khác để nhập tồn tại: 

import MyDefaultExportedClass, { Class1, Class2 } from "./SomeFile";
import MyDefaultExportedClass, * as Classes from "./SomeFile";
import "./SomeFile"; // runs SomeFile.js without importing any exports

3
những gì đã xảy ra import myAlias = require("./PathToFile")và có export = IInterfaceOrClasstrong tập tin? Đó có phải là lỗi thời bây giờ?
BenCr

@BenCr vâng, đây là cách es6 mới
David Sherret

Tại sao bạn không đưa ra một ví dụ về 'Xuất khẩu được đặt tên'?
Stato Machino

aws-sdk / client / sns không có xuất khẩu mặc định và khi truy cập sns bằng cách nhập sns từ '/ sns' tôi không nhận được xuất nhưng nhập myAlias ​​= quiries ("./ PathToFile") hoạt động. Tôi có thể làm gì đó để thay đổi nó nhập sns từ '/ sns' mà không thực hiện thay đổi nguồn không?
Jeson Dias

Nếu bạn không đặt từ khóa một cách rõ ràng defaultthì vẫn có một bản xuất mặc định có sẵn trong tệp đó? nếu vậy các quy tắc là gì.
Simon_Weaver

10

Tôi đã cố gắng giải quyết vấn đề tương tự, nhưng tìm thấy một lời khuyên thú vị của Basarat Ali Syed , về sự nổi tiếng của TypeScript Deep Dive , rằng chúng ta nên tránh export defaulttuyên bố chung cho một lớp, và thay vào đó hãy nối thêmexport thẻ vào khai báo lớp. Thay vào đó, lớp đã nhập nên được liệt kê trong importlệnh của mô-đun.

Đó là: thay vì

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

và đơn giản import Foo from './foo';trong mô-đun sẽ nhập, người ta nên sử dụng

export class Foo {
    // ...
}

import {Foo} from './foo' trong nhà nhập khẩu.

Lý do cho điều đó là những khó khăn trong việc tái cấu trúc các lớp và công việc thêm vào để xuất khẩu. Bài viết gốc của Basarat là export defaultcó thể dẫn đến các vấn đề


0

Đây là ví dụ với xuất đối tượng đơn giản.

var MyScreen = {

    /* ... */

    width : function (percent){

        return window.innerWidth / 100 * percent

    }

    height : function (percent){

        return window.innerHeight / 100 * percent

    }


};

export default MyScreen

Trong tệp chính (Sử dụng khi bạn không muốn và không cần tạo phiên bản mới) và nó không phải là toàn cầu, bạn sẽ chỉ nhập tệp này khi cần:

import MyScreen from "./module/screen";
console.log( MyScreen.width(100) );
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.