'Khai báo' làm gì trong 'xuất khai báo các hành động của lớp'?


Câu trả lời:


212

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


Tôi có một kịch bản tương tự với một JS bên ngoài xác định một biến 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?
Alejandro González

94

Để 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.


2
"Cả hai ví dụ mã sẽ cho kết quả trong cùng một sản lượng JavaScript", đó không phải là đúng: declare var myLibrarysẽ transpile không có gì: typescriptlang.org/play/#code/...
apollo

38

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:

  • Khi 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.
  • Vì chúng tôi biết các loại, chúng tôi (có khả năng) có quyền truy cập vào IDE Intellisense của chúng tôi .
  • Vì chúng tôi biết các loại, trình biên dịch bản thảo có thể kiểm tra các loại tại thời gian biên dịch và có thể cảnh báo chúng tôi nếu chúng tôi đang sử dụng các loại sai trong các tình huống nhất định.

18

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 {
    ...
}

Tôi không nghĩ chúng giống nhau, cái trước cần sử dụng import, cái sau không
Ian Zhong

10

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!


Namespace bên trong module ala export namespacekhô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.
ford04
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.