Hvorfor bryter importering av en node-modul mine interne Typescript-navnerom i atom-typescript?
Jeg har et veldig lite Node Typescript-prosjekt med følgende struktur:
Når jeg prøver å importere modulen "diff" i filen min index.ts på denne måten:
import * as diff from 'diff';
Atom-typescript mister plutselig evnen til å finne mitt "fgtApp.Interfaces"-navnerom:
Så snart jeg fjerner import-setningen, kan node løse opp navnerommet «fgtApp.Interfaces» uten problemer, slik:
Er dette en feil i atom-typescript eller en feil i min forståelse av hvordan importering av disse eksterne modulene fungerer?
Svar #1
Dette er ikke spesifikt et problem med atom-typescript. Atom-typescript-pluginen bruker den offisielle TypeScript-språkservicen (samme som Visual Studio), så dette ville være et problem i hvilken som helst editor.
Problemet er at når du har angitt en import eller eksport, blir filen et modul ("eksternt modul" før TypeScript 1.5). Dette betyr at når import * as diff from 'diff'; er til stede, blir ting som er erklært i index.ts kun lokale og tas ikke med i/merges med det globale navnerommet.
TypeScript-spesifikasjon, seksjon 11.1: ...kildefiler som inneholder minst én ekstern importdeklarasjon, eksportoppgave, eller toppnivå eksportert deklarasjon anses som separate eksterne moduler. Entiteter deklarert i en ekstern modul er kun tilgjengelige i den modulen, men eksporterte entiteter kan importeres til andre moduler ved hjelp av importdeklarasjoner
Når du ikke bruker eksterne moduler, lar TypeScript navneområder i forskjellige filer bygge videre på hverandre. Når du begynner å bruke eksterne moduler, er dette ikke lenger tilfelle uten å bruke løsninger. I dette tilfellet er det ofte best å bare bytte til å bruke eksterne moduler - hvis du lager et Node-prosjekt, er dette spesielt enkelt fordi du ikke trenger å bekymre deg for pakking.
I stedet for et "dypt navneområde" (f.eks. fgtApp.category.thing) som C# og .NET oppmuntrer til - begynn å tenke på hver TypeScript-kildefil som sitt eget modul. Hvis du virkelig ønsker en hierarki, implementer det med en mappestruktur.
Denne koden vil fungere som forventet selv med noImplicitAny aktiv:
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;
}
service.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);


