Câu trả lời:
tìm thấy những gì tôi đang tìm kiếm:
Khai báo so với var
vartạo ra một biến mới. declaređược sử dụng để báo cho TypeScript rằng biến đã được tạo ở nơi khác. Nếu bạn sử dụng declare, không có gì được thêm vào JavaScript được tạo - nó chỉ đơn giản là một gợi ý cho trình biên dịch.
Ví dụ: nếu bạn sử dụng tập lệnh bên ngoài xác định var externalModule, bạn sẽ sử dụng declare var externalModuleđể gợi ý cho trình biên dịch TypeScript externalModuleđã được thiết lập
externalModuletrong số các biến khác. Điều gì có thể là lý do tại sao externalModulekhông được xác định trong thời gian chạy nhưng một số biến khác thì không?
Để hiểu điều này, trước tiên bạn phải hiểu từ khóa "khai báo".
Đây là một lời giải thích tốt từ Blog của Gil Fink :
Từ khóa khai báo TypeScript được sử dụng để khai báo các biến có thể không có nguồn gốc từ tệp TypeScript.
Ví dụ: hãy tưởng tượng rằng chúng ta có một thư viện gọi là myL Library không có tệp khai báo TypeScript và có một không gian tên gọi là myL Library trong không gian tên toàn cục. Nếu bạn muốn sử dụng thư viện đó trong mã TypeScript của mình, bạn có thể sử dụng mã sau:
declare var myLibrary;Kiểu mà bộ thực thi TypeScript sẽ cung cấp cho biến myL Library là loại bất kỳ. Vấn đề ở đây là bạn sẽ không có Intellisense cho biến đó trong thời gian thiết kế nhưng bạn sẽ có thể sử dụng thư viện trong mã của mình. Một tùy chọn khác để có hành vi tương tự mà không sử dụng từ khóa khai báo là chỉ sử dụng một biến với bất kỳ loại nào:
var myLibrary: any;Cả hai ví dụ mã sẽ dẫn đến cùng một đầu ra JavaScript nhưng ví dụ khai báo dễ đọc hơn và thể hiện một khai báo xung quanh.
Vì vậy, sau khi bạn hiểu từ khóa "khai báo", hãy quay lại bất cứ nơi nào bạn tìm thấy
export declare class Action{
...
}
Việc triển khai thực sự của lớp có lẽ ở một nơi nào khác có thể là tập tin .js.
declare var myLibrarysẽ transpile không có gì: typescriptlang.org/play/#code/...
declare trong bản đánh máy:Các declaretừ khóa trong nguyên cảo là hữu ích cho nói trình biên dịch nguyên cảo rằng một tuyên bố được xác định ở một nơi khác (ở đâu đó bằng văn bản trong một tập tin javascript bên ngoài hoặc một phần của môi trường runtime).
Giả sử chúng ta có một biến gọi là foo được khai báo ở một nơi khác. Sau đó, khi chúng ta cố gắng tham chiếu biến, trình biên dịch typcript sẽ đưa ra lỗi:
foo = 'random'; // Error: 'foo' is not defined
Chúng tôi có thể khắc phục vấn đề này bằng cách sử dụng declaretừ khóa:
declare var foo: string;
foo = 'random'; // no error anymore
Điều này có hậu quả sau đây:
foothực sự không được khai báo ở bất kỳ nơi nào khác và chúng tôi cố gắng sử dụng biến có thể xảy ra lỗi thời gian chạy. Vì vậy, chỉ sử dụngdeclare từ khóa khi bạn biết biến có sẵn tại thời điểm này.Các khai báo từ khóa trong trường hợp cụ thể này:
export declare class Actions {
...
}
... Rõ ràng là vô dụng và tôi nghĩ TypeScript nên xem xét việc gây ra lỗi này (tôi không biết có lý do ẩn nào không). Nếu bạn khai báo một lớp, bạn sẽ không bao giờ cần phải nhập nó. Nếu bạn xuất một lớp mong muốn ai đó nhập nó, bạn không cần phải khai báo nó. Và bởi vì bạn đang khai báo lớp này, theo định nghĩa, lớp này sẽ có thể sử dụng được mà không cần phải nhập nó. Nhưng điều này không đúng khi bạn xuất khai báo một lớp. Bạn cần nhập nó để sử dụng.
TL; DR
export declare class Actions {
...
}
giống như
declare class Actions {
...
}
import, cái sau không
declare - không có bất kỳ từ khóa nhập hoặc xuất nào - xác định các tệp khai báo được TypeScript tự động chọn, đây là một tính năng hữu ích để thêm gõ vào các mô-đun kế thừa (các gói được cài đặt npm không có định nghĩa TypeScript).
import / export là cách thích hợp để sử dụng các mô-đun và mọi thứ cần phải được nhập thủ công (và tôi thấy hơi tẻ nhạt) được nhập, hoặc là logic, hoặc là định nghĩa.
Là trường hợp sử dụng thực tế, export declarecho phép bạn tránh xuất tất cả các thành phần phụ, ví dụ:
export declare namespace Redux {
namespace Store {
interface Definition { ... }
}
}
Có thể dễ đọc hơn:
export namespace Redux {
export namespace Store {
export interface Definition { ... }
}
}
Nhập khẩu bên ngoài là như nhau trong cả hai trường hợp (ví dụ import { Redux } from 'definitions/redux'; ), mà tôi không biết liệu nó có thực hành tốt hay không, nhưng tôi thấy nó gọn gàng! ^^
Điều quan trọng cần lưu ý là việc thêm một importhoặc exportvào tệp của bạn sẽ thúc đẩy nó trở thành một mô-đun, do đó declarephạm vi sẽ không còn ở cấp độ toàn cầu nữa.
PS, có một lỗi ( vấn đề 16671 ): nếu bạn sử dụng const enumtrong khai báo của mình (tôi thực hiện điều đó cho loại hành động redux) và bạn đã chỉ định transpileOnlycờ (gói tạo kiểu phản ứng-ứng dụng , đó là lý do tôi biết), enum sẽ không được nội tuyến! Bạn có thể chạy trong đó, bạn có thể không, nhưng thật hữu ích khi biết trước!
export namespacelà không phải là một ý tưởng tốt và thêm namespacing không cần thiết . Về export declare, hãy xem câu trả lời của André Pena.