2015-09-11 14 views
6

Ho un piccolo progetto nodo tipografico con la seguente struttura:Perché l'importazione di un modulo nodo interrompe i miei spazi dei nomi Typescript interni in atom typescript?

App structure

Quando si tenta di importare il modulo "diff" nei miei index.ts file in questo modo:

import * as diff from 'diff'; 

Atom -typescript perde improvvisamente la capacità di individuare il mio spazio dei nomi "fgtApp.Interfaces":

Loses autocomplete of internal namespace

.210

Appena posso rimuovere l'istruzione import, il nodo è in grado di risolvere i "fgtApp.Interfaces" namespace alcun problema in questo modo:

Autocomplete working properly without import declaration

È questo un bug in atomo di macchina o un bug nel la mia comprensione del modo in cui l'importazione di questi moduli esterni funziona?

+1

perché diventa un modulo di file: http://basarat.gitbooks.io/typescript/content/docs/project/modules.html – basarat

+0

@ basarat quindi non c'è modo che questo DOVREBBE funzionare? Sembra che sarebbe davvero aiutare a mantenere il codice in ordine. Ho scritto una domanda simile qui: http://stackoverflow.com/questions/34852909/using-angular-2-with-typescript-and-namespaces – Askanison4

+0

@ askanison4 soluzione possibile potrebbe essere la rimozione di 'import * come diff da 'diff '; 'e utilizza il modulo diff come' diff.property' –

risposta

6

Questo non è specificamente un problema con dattiloscritto atomico. Il plug-tip dattiloscopico usa il servizio di lingua TypeScript ufficiale (come Visual Studio), quindi questo sarebbe un problema in qualsiasi editor.

Il problema è che una volta specificata l'importazione o l'esportazione, il file diventa un modulo ("modulo esterno" pre-TypeScript 1.5). Ciò significa che quando è presente lo import * as diff from 'diff';, le cose dichiarate in index.ts diventano solo locali e non considerano/si uniscono nello spazio dei nomi globale.

tipografico spec, sezione 11.1: ... file di origine che contengono almeno un dichiarazione esterna di importazione, assegnazione di esportazione, o di livello superiore di dichiarazione esportati sono considerati i moduli esterni separati. Entità dichiarate in un modulo esterno sono di portata solo in quel modulo, ma entità esportate possono essere importate in altri moduli utilizzando le dichiarazioni di importazione

Quando non si utilizza moduli esterni, dattiloscritto consente spazi dei nomi in diversi file su costruite l'un l'altro. Una volta che si inizia a utilizzare moduli esterni, questo non è più il caso senza l'uso di soluzioni alternative. In questo caso, è spesso preferibile passare semplicemente all'utilizzo di moduli esterni: se stai realizzando un progetto Node, questo è particolarmente semplice perché non devi preoccuparti del raggruppamento.

Invece di un "deep namespace" (ad esempio fgtApp.category.thing) come C# e .NET incoraggia - inizia a pensare a ciascun file di origine TypeScript come a un modulo. Se vuoi davvero una gerarchia, implementane una con una struttura di cartelle.

Questo codice funzionerà come ci si aspetta anche con noImplicitAny attiva:

interfaces.d.ts

// Notice that this is a d.ts file. Since it will only contain interfaces, 
// making it a d.ts file means TypeScript doesn't have to worry about 
// emitting it and you also can't accidentally put executable code here. 
export interface IFgtService { 
    authenticateDisable: boolean; 
    failedAttempt: boolean; 
    authenticate: (username: string, password: string) => boolean; 
} 

export interface IAnotherInterfaceAsAnExample { 
    isCool: boolean; 
} 

servizio.ts

// since there is no "relative path", diff will come from node_modules. 
import * as diff from 'diff'; 
// since there IS a relative path, interfaces will come from ./interfaces.d.ts 
import * as interfaces from './interfaces'; 

// You can still use namespaces inside an "external module", but mainly they 
// serve as a convenient way to bundle stuff for a one-line export (see 
// the last line of this file). 
namespace Service { 
    export class FgtService implements interfaces.IFgtService { 
    authenticateDisable = true; 
    failedAttempt = true; 
    authenticate = (username: string, password: string) => { 
     let d = diff.d; 
     return true; 
    } 
    } 
} 
export = Service; 

index.ts

import {FgtService} from './Service'; 

const myService = new FgtService(); 
console.log(myService.authenticateDisable); 
+0

Per curiosità; Lei parla di soluzioni alternative. Cosa sarebbero? NOTA: ho sollevato una domanda simile qui: http://stackoverflow.com/questions/34852909/using-angular-2-with-typescript-and-namespaces – Askanison4

+0

Un esempio di soluzione alternativa potrebbe essere la scrittura di tutto il codice in il modo dello spazio dei nomi globale e quindi scrivere un preprocessore per unire gli spazi dei nomi insieme sotto un insieme di moduli nello stile esterno. Non intendevo indicare che ciò sarebbe stato facile o ben fatto. – NYCdotNet

Problemi correlati