2015-06-21 3 views
14

Nel mio esempio, sto cercando di estendere l'interfaccia TS Window per includere un polyfill per fetch. Perché non importa. La domanda è: "Come faccio a dire che TS window.fetch è una funzione valida?"Come estendere l'interfaccia dattilografica 'Finestra'

sto facendo questo in codice VS, v.0.3.0, che è in esecuzione TS v.1.5 (IIRC).

dichiarando l'interfaccia dentro il mio file di classe TS dove voglio usarlo non funziona:

///<reference path="typings/tsd.d.ts"/> 

interface Window { 
    fetch:(url: string, options?: {}) => Promise<any> 
} 
... 
window.fetch('/blah').then(...); // TS objects that window doesn't have fetch 

ma va bene se dichiaro questa stessa interfaccia in un separato ".d.ts" file e fare riferimento a esso nel mio file di classe TS.

qui è "tipizzazioni/window.extend.d.ts"

///<reference path="es6-promise/es6-promise"/> 
interface Window { 
    fetch:(url: string, options?: {}) => Promise<any> 
} 

Ora posso usarlo nella mia TS file di classe:

///<reference path="typings/window.extend.d.ts"/> 
... 
window.fetch('/blah').then(...); // OK 

In alternativa, posso scrivere un'interfaccia che si estende con un altro nome nel mio file di classe TS e quindi utilizzarlo in un cast:

interface WindowX extends Window { 
    fetch:(url: string, options?: {}) => Promise<any> 
} 
... 
(<WindowX> window).fetch('/blah').then(...); // OK 

Perché l'estensione dell'interfaccia funziona in "d.ts" ma non in loco?

Devo davvero passare attraverso queste rotazioni?

+0

Una domanda per chiarire .... Qual è il modo migliore per realizzare l'estensione di un interfaccia? Vedo pro e contro per entrambi questi –

risposta

10

Quando si ha un livello superiore import o export nel file (che si deve da qualche parte per essere avere questo problema), il file è un modulo esterno .

In un modulo esterno, la dichiarazione di un'interfaccia crea sempre un nuovo tipo anziché aumentare un'interfaccia globale esistente. Ciò simula il comportamento generale dei caricatori di moduli: le cose dichiarate in questo file non si fondono o interferiscono con le cose nell'ambito globale.

Il motivo di questa rotazione è che altrimenti non ci sarebbe un modo per, in un modulo esterno, definire nuove variabili o tipi con lo stesso nome di quelli nell'ambito globale.

+0

È possibile fornire un collegamento ad alcuni documenti su questo problema? Forse la voce wiki [Dichiarazione di fusione] (https://github.com/Microsoft/TypeScript/wiki/Declaration-Merging) deve essere estesa? –

+0

I ** do ** hanno istruzioni 'import' di primo livello. Quello che dici ha senso ora che capisco. Ma ancora non conosco i pro/contro dei due approcci che hanno funzionato o se c'è una terza via migliore.Sono sicuro che estendere 'window' sarà uno scenario comune che dovrebbe essere chiaramente documentato. [Dichiarazione di fusione] (https://github.com/Microsoft/TypeScript/wiki/Declaration-Merging) ha sicuramente bisogno di elaborazione ... soprattutto visto che l'esempio di 'documento di esempio' * non funzionerebbe nel mio caso d'uso *! – Ward

+3

Adoriamo le digitazioni quando sono accurate. Li detestiamo quando non lo sono. È importante avere un percorso pulito per estenderli. Mi piacerebbe conoscere anche altre opzioni qui –

6

è necessario il declare global

declare global { 
    interface Window { 
    fetch:(url: string, options?: {}) => Promise<any> 
    } 
} 

Questo funziona allora:

window.fetch('/blah').then(...); 
+0

Stai usando il webpack? Per me, le cose che dichiaro globalmente in un modulo non sono visibili in altri moduli. Qualche indizio? – mayid