javascript - TypeScript ES6 import-modul "Filen er ikke en modul-feil"
Jeg bruker TypeScript 1.6 med ES6-modulsyntaks.
Filene mine er:
test.ts:
module App {
export class SomeClass {
getName(): string {
return 'name';
}
}
}
main.ts:
import App from './test';
var a = new App.SomeClass();
Når jeg prøver å kompilere main.ts-filen, får jeg denne feilen:
Feil TS2306: Filen 'test.ts' er ikke et modul.
Hvordan kan jeg oppnå det?
Svar #1
Utvidet - for å gi flere detaljer basert på noen kommentarer
Feilen
Feil TS2306: Filen 'test.ts' er ikke et modul.
Kommer fra fakta beskrevet her http://exploringjs.com/es6/ch_modules.html
17. Moduler
Dette kapittelet forklarer hvordan de innebygde modulene fungerer i ECMAScript 6.
17.1 Oversikt
I ECMAScript 6 lagres moduler i filer. Det er nøyaktig én modul per fil og én fil per modul. Du har to måter å eksportere ting fra en modul på. Disse to måtene kan blandes, men det er vanligvis bedre å bruke dem separat.
17.1.1 Flere navngitte eksporteringer
Det kan være flere navngitte eksporteringer:
//------ lib.js ------ export const sqrt = Math.sqrt; export function square(x) { return x * x; } export function diag(x, y) { return sqrt(square(x) + square(y)); } ...17.1.2 Enkel standardeksport
Det kan være ett enkelt standardeksport. For eksempel en funksjon:
//------ myFunc.js ------ export default function () { ··· } // no semicolon!
Basert på det ovenstående trenger vi export, som en del av test.js-filen. La oss justere innholdet i den på denne måten:
// test.js - exporting es6
export module App {
export class SomeClass {
getName(): string {
return 'name';
}
}
export class OtherClass {
getName(): string {
return 'name';
}
}
}
Og nå kan vi importere det på disse tre måtene:
import * as app1 from "./test";
import app2 = require("./test");
import {App} from "./test";
Og vi kan konsumere importerte ting som dette:
var a1: app1.App.SomeClass = new app1.App.SomeClass();
var a2: app1.App.OtherClass = new app1.App.OtherClass();
var b1: app2.App.SomeClass = new app2.App.SomeClass();
var b2: app2.App.OtherClass = new app2.App.OtherClass();
var c1: App.SomeClass = new App.SomeClass();
var c2: App.OtherClass = new App.OtherClass();
og kall metoden for å se den i aksjon:
console.log(a1.getName())
console.log(a2.getName())
console.log(b1.getName())
console.log(b2.getName())
console.log(c1.getName())
console.log(c2.getName())
Den opprinnelige delen prøver å bidra til å redusere mengden kompleksitet i bruk av navnerommet
Original del:
Jeg vil virkelig sterkt foreslå å sjekke denne Q&A:
Hvordan bruker jeg navneområder med TypeScript eksterne moduler?
La meg sitere den første setningen:
Ikke bruk «namespaces» i eksterne moduler.
Ikke gjør dette.
Alvorlig talt. Stopp.
...
I dette tilfellet trenger vi bare ikke module inne i test.ts. Dette kan være innholdet i det justert test.ts:
export class SomeClass
{
getName(): string
{
return 'name';
}
}
Les mer her
Eksport =
I det forrige eksemplet, når vi brukte hver validator, eksporterte hver modul bare én verdi. I tilfeller som dette er det tungvint å arbeide med disse symbolene gjennom deres kvalifiserte navn når en enkelt identifikator ville vært like greit.
Syntaksen
export =spesifiserer et enkelt objekt som eksporteres fra modulen. Dette kan være en klasse, grensesnitt, modul, funksjon eller enum. Når det importeres, brukes det eksporterte symbolet direkte og er ikke kvalifisert med noe navn.
vi kan senere bruke det slik:
import App = require('./test');
var sc: App.SomeClass = new App.SomeClass();
sc.getName();
Les mer her:
Valgfri modulinnlasting og andre avanserte lastescenarier
I noen tilfeller kan du ønske å bare laste en modul under visse forhold. I TypeScript kan vi bruke mønsteret vist nedenfor for å implementere dette og andre avanserte lastescenarier for å direkte kalle modul-lasterne uten å miste typesikkerheten.
Kompilatoren oppdager om hver modul brukes i den genererte JavaScript-koden. For moduler som bare brukes som en del av typesystemet, blir ingen require-anrop generert. Denne fjerningen av ubrukte referanser er en god ytelsesoptimalisering, og gjør det også mulig med valgfri lasting av disse modulene.
Kjerneideen i mønsteret er at import-id=krever('... ')-setningen gir oss tilgang til typene som eksponeres av den eksterne modulen. Modullasteren aktiveres dynamisk (gjennom require), som vist i if-blokkene nedenfor. Dette utnytter referanseutvelgelsesoptimaliseringen slik at modulen kun lastes inn når det trengs. For at dette mønsteret skal fungere, er det viktig at symbolet definert via import kun brukes i typeposisjoner (dvs. aldri i en posisjon som ville blitt lagt inn i JavaScript).
Svar #2
Svarene ovenfor er riktige. Men bare for sikkerhets skyld... Fikk samme feil i VS Code. Måtte lagre/kompilere filen på nytt som ga feil.
Svar #3
Hvordan kan jeg få til det?
Ditt eksempel erklærer et TypeScript < 1.5 internmodul, som nå kalles et navnerom. Den gamle module App {}-syntaksen tilsvarer nå namespace App {}. Som et resultat fungerer følgende:
// test.ts
export namespace App {
export class SomeClass {
getName(): string {
return 'name';
}
}
}
// main.ts
import { App } from './test';
var a = new App.SomeClass();
Når det er sagt...
Prøv å unngå å eksportere namespaces og eksporter heller moduler (som tidligere ble kalt eksterne moduler). Hvis det er nødvendig, kan du bruke et namespace ved import med namespace import-mønsteret slik:
// test.ts
export class SomeClass {
getName(): string {
return 'name';
}
}
// main.ts
import * as App from './test'; // namespace import pattern
var a = new App.SomeClass();
Svar #4
I tillegg til A. Tims svar finnes det tider hvor selv det ikke fungerer, så du må:
- Skriv om import-strengen ved å bruke intellisense. Noen ganger løser dette problemet
- Start VS Code på nytt
