Cosa fa "declare" in "esporta le azioni della classe di dichiarazione"?


Risposte:


212

trovato quello che stavo cercando:

Dichiarare vs. var

varcrea una nuova variabile. declareè usato per dire a TypeScript che la variabile è stata creata altrove. Se si utilizza declare, nulla viene aggiunto al JavaScript generato: è semplicemente un suggerimento per il compilatore.

Ad esempio, se si utilizza uno script esterno che definisce var externalModule, è possibile utilizzare declare var externalModuleper suggerire il compilatore TypeScript che externalModuleè già stato impostato


Ho uno scenario simile con un JS esterno che definisce una variabile externalModuletra gli altri. Quale potrebbe essere il motivo per cui externalModulenon è definito in fase di esecuzione ma alcune delle altre variabili no?
Alejandro González,

94

Per capirlo, devi prima capire la parola chiave "dichiarare".

Ecco una buona spiegazione dal blog di Gil Fink :

La parola chiave declare TypeScript viene utilizzata per dichiarare variabili che potrebbero non essere state originate da un file TypeScript.

Ad esempio, immaginiamo di avere una libreria chiamata myLibrary che non ha un file di dichiarazione TypeScript e uno spazio dei nomi chiamato myLibrary nello spazio dei nomi globale. Se si desidera utilizzare quella libreria nel codice TypeScript, è possibile utilizzare il seguente codice:

declare var myLibrary;

Il tipo che il runtime TypeScript fornirà alla variabile myLibrary è qualsiasi tipo. Il problema qui è che non avrai Intellisense per quella variabile in fase di progettazione ma sarai in grado di usare la libreria nel tuo codice. Un'altra opzione per avere lo stesso comportamento senza usare la parola chiave declare è semplicemente usare una variabile con qualsiasi tipo:

var myLibrary: any;

Entrambi gli esempi di codice genereranno lo stesso output JavaScript, ma l'esempio di dichiarazione è più leggibile ed esprime una dichiarazione ambientale.


Quindi, dopo aver compreso la parola chiave "dichiara", torna a dove trovi

export declare class Action{
...
}

La vera implementazione della classe è probabilmente da qualche altra parte, forse un file .js.


2
"Entrambi gli esempi di codice produrranno lo stesso output JavaScript", il che non è vero: declare var myLibrarysi tradurrà in nulla: typescriptlang.org/play/#code/…
apollo

38

declare in dattiloscritto:

La declareparola chiave in typescript è utile per dire al compilatore di typescript che una dichiarazione è definita altrove (da qualche parte scritta in un file javascript esterno o parte dell'ambiente di runtime).

Diciamo che abbiamo una variabile chiamata foo dichiarata altrove. Quando proviamo quindi a fare riferimento alla variabile, il compilatore dattiloscritto genererà un errore:

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

Possiamo risolvere questo problema usando la declareparola chiave:

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

Ciò ha le seguenti conseguenze:

  • Quando in foorealtà non viene dichiarato altrove, e proviamo a utilizzare la variabile potrebbe verificarsi un errore di runtime. Quindi usa la declareparola chiave solo quando sai che la variabile è disponibile a questo punto.
  • Poiché conosciamo i tipi, (potenzialmente) otteniamo l'accesso al nostro IDE Intellisense .
  • Poiché conosciamo i tipi, il compilatore dattiloscritto può controllare i tipi in fase di compilazione e può avvisarci se stiamo utilizzando tipi errati in determinati scenari.

18

La parola chiave dichiarare in questo caso specifico:

export declare class Actions {
    ...
}

... è apparentemente inutile e penso che TypeScript dovrebbe prendere in considerazione l'idea di renderlo un errore (non so se c'è un motivo nascosto). Se dichiari una classe, non dovrai mai importarla. Se esporti una classe in attesa che qualcuno la importi, non è necessario dichiararla. E poiché stai dichiarando questa classe, per definizione, questa classe dovrebbe essere utilizzabile senza la necessità di importarla. Ma questo non è vero quando si esporta dichiarare una classe. È necessario importarlo per l'uso.

TL; DR

export declare class Actions {
    ...
}

equivale a

declare class Actions {
    ...
}

Non penso che siano uguali, il primo deve essere utilizzato import, il secondo no
Ian Zhong il

10

declare - senza parole chiave di importazione o esportazione - definisce i file di dichiarazione scelti automaticamente da TypeScript, che è una funzione utile per aggiungere la digitazione ai moduli legacy (pacchetti installati npm senza definizioni TypeScript).

import/ exportè il modo corretto di usare i moduli e tutto deve essere importato manualmente (e lo trovo un po 'noioso), sia logico, sia definizioni.

Come pratico caso d'uso, export declareti consente di evitare di esportare tutti gli elementi secondari, ad esempio:

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

Quale può essere più facile da leggere di:

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

L'importazione esterna è la stessa in entrambi i casi (ad es. import { Redux } from 'definitions/redux';), Che non so se sia una buona pratica o no, ma la trovo ordinata! ^^

È importante tenere presente che l'aggiunta di un importo exportal tuo file lo promuoverà come modulo, pertanto l' declareambito non sarà più a livello globale.

PS, c'è un bug ( problema 16671 ): se usi const enumnella tua dichiarazione (lo faccio per il tipo di azioni redux) e hai specificato il transpileOnlyflag (il pacchetto create -eagire-app-dattiloscritto fa, ecco perché lo so), il enum non sarà inline! Potresti correre, non puoi, ma è utile saperlo in anticipo!


Gli spazi dei nomi all'interno dei moduli ala nonexport namespace sono una buona idea e aggiungono spazi dei nomi inutili . Per quanto riguarda export declare, dai un'occhiata alla risposta di André Pena.
ford04
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.