Що означає "оголосити" у "експорті оголосити дії класу"?


Відповіді:


212

знайшов те, що я шукав:

Заявити проти вар

varстворює нову змінну. declareвикористовується для того, щоб повідомити TypeScript, що змінна створена в іншому місці. Якщо ви використовуєте declare, до створеного JavaScript нічого не додається - це просто натяк на компілятор.

Наприклад, якщо ви використовуєте зовнішній скрипт, який визначає var externalModule, ви б declare var externalModuleпідказали на компілятор TypeScript, externalModuleякий вже був налаштований


У мене схожий сценарій із зовнішнім JS, що визначає змінну externalModuleсеред інших. Що може бути причиною того externalModule, що під час виконання не визначено, але деякі інші змінні ні?
— Алехандро Гонсалес

94

Щоб зрозуміти це, потрібно спершу зрозуміти ключове слово «оголосити».

Ось хороше пояснення з блогу Гіл Фінка :

Ключове слово декларації TypeScript використовується для оголошення змінних, які, можливо, не походять з файлу TypeScript.

Наприклад, давайте уявимо, що в глобальній просторі імен у нас є бібліотека під назвою myLibrary, яка не має файлу декларування TypeScript і має простір імен під назвою myLibrary. Якщо ви хочете використовувати цю бібліотеку у своєму коді TypeScript, ви можете використовувати такий код:

declare var myLibrary;

Тип, який час виконання TypeScript надасть змінній myLibrary - це будь-який тип. Проблема тут полягає в тому, що ви не будете мати Intellisense для цієї змінної в проектний час, але ви зможете використовувати бібліотеку у своєму коді. Інший варіант мати таку ж поведінку без використання ключового слова оголосити - це просто використання змінної з будь-яким типом:

var myLibrary: any;

Обидва приклади коду призведуть до того ж виводу JavaScript, але приклад оголошення є більш читабельним і виражає зовнішнє оголошення.


Тож після того, як ви зрозумієте ключове слово "оголосити", поверніться туди, де знайдете

export declare class Action{
...
}

Реальна реалізація класу, ймовірно, десь в іншому місці - можливо, файл .js.


2
"Обидва приклади коду призведуть до однакового виводу JavaScript", що не відповідає дійсності: declare var myLibraryпереведеться в ніщо: typecriptlang.org/play/#code/…
— apollo

38

declare в машинописному тексті:

declareКлючове слово в машинопису корисно говорити машинопис компілятор , що декларація визначається де - то ще (де - то написано в зовнішньому файлі або частини середовища виконання).

Скажімо, у нас є змінна під назвою foo, декларована десь в іншому місці. Коли ми спробуємо посилатися на змінну, компілятор typecript видасть помилку:

foo = 'random'; // Error: 'foo' is not defined

Ми можемо виправити цю проблему за допомогою declareключового слова:

declare var foo: string;
foo = 'random';  // no error anymore

Це має такі наслідки:

  • Якщо fooнасправді ніде не оголошено, і ми намагаємось використовувати змінну, може виникнути помилка виконання. Тому використовуйте declareключове слово лише тоді, коли вам відомо, що змінна доступна в цей момент.
  • Оскільки ми знаємо типи, ми (потенційно) отримуємо доступ до нашого Ідентифікатора IDE .
  • Оскільки ми знаємо типи, компілятор typecript може перевірити типи під час компіляції та може попередити нас, якщо ми використовуємо неправильні типи в певних сценаріях.

18

Оголосити ключове слово в даному конкретному випадку:

export declare class Actions {
    ...
}

... мабуть марно, і я думаю, що TypeScript повинен розглянути можливість помилки (я не знаю, чи є прихована причина). Якщо ви декларуєте клас, вам ніколи не потрібно буде імпортувати його. Якщо ви експортуєте клас, очікуючи, що хтось його імпортує, вам не потрібно декларувати його. А оскільки ви декларуєте цей клас, за визначенням, цей клас повинен бути придатним для використання без необхідності його імпорту. Але це неправда, коли ви експортуєте декларувати клас. Вам потрібно імпортувати його для використання.

TL; DR

export declare class Actions {
    ...
}

те саме, що

declare class Actions {
    ...
}

Я не думаю, що вони однакові, першим потрібно користуватися import, другим
— Іен Чжун

10

declare - без будь-яких ключових слів імпорту чи експорту - визначає файли декларацій, автоматично вибрані TypeScript, що є корисною функцією для додавання тексту в застарілі модулі (встановлені пакети npm без визначення TypeScript).

import/ export- це правильний спосіб використання модулів, і все потрібно імпортувати вручну (і я вважаю трохи стомлюваним), або це логіка, або це визначення.

Що стосується практичного використання, export declareдозволяє уникнути експорту всіх піделементів, наприклад:

export declare namespace Redux {
    namespace Store {
        interface Definition { ... }
    }
}

Що може бути простішим для читання, ніж:

export namespace Redux {
    export namespace Store {
        export interface Definition { ... }
    }
}

Зовнішній імпорт є однаковим в обох випадках (наприклад import { Redux } from 'definitions/redux';), що я не знаю, добре це чи ні, але я вважаю це охайним! ^^

Важливо пам’ятати, що додавання файлу importабо exportдо вашого файлу сприятиме тому, що він буде модулем, тому declareобсяг вже не буде на глобальному рівні.

PS, є помилка ( випуск 16671 ): якщо ви використовуєте const enumу своїй декларації (я це роблю для типу операцій скорочення), і ви вказали transpileOnlyпрапор ( пакет create-react-app-typecript does, тому я знаю), перерахунок не буде накреслений! Ви можете бігати в ньому, ви можете, але це корисно заздалегідь знати!


Простори імен всередині модулів ala - export namespaceце не дуже гарна ідея та додайте непотрібний простір імен . Стосовно export declare, подивіться на відповідь Андре Пена.
— ford04
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.