javascript - TypeScript ES6 import modul „Fișierul nu este un modul eroare”
Folosesc TypeScript 1.6 cu sintaxa modulelor ES6.
Fișierele mele sunt:
test.ts:
module App {
export class SomeClass {
getName(): string {
return 'name';
}
}
}
main.ts:
import App from './test';
var a = new App.SomeClass();
Când încerc să compilez fișierul main.ts, primesc această eroare:
Eroare TS2306: Fișierul 'test.ts' nu este un modul.
Cum pot realiza asta?
Răspuns #1
Extins - pentru a oferi mai multe detalii pe baza unor comentarii
Eroarea
Eroare TS2306: Fișierul 'test.ts' nu este un modul.
Vine din faptul descris aici http://exploringjs.com/es6/ch_modules.html
17. Module
Acest capitol explică modul în care funcționează modulele încorporate în ECMAScript 6.
17.1 Prezentare generală
În ECMAScript 6, modulele sunt stocate în fișiere. Există exact un modul pe fișier și un fișier pe modul. Ai două modalități de a exporta lucruri dintr-un modul. Aceste două modalități pot fi combinate, dar de obicei este mai bine să le folosești separat.
17.1.1 Mai multe exporturi numite
Pot exista exporturi denumite multiple:
//------ 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 Export implicit unic
Poate exista un singur export implicit. De exemplu, o funcție:
//------ myFunc.js ------ export default function () { ··· } // no semicolon!
Pe baza celor de mai sus avem nevoie de export, ca parte a fișierului test.js. Haideți să ajustăm conținutul acestuia astfel:
// test.js - exporting es6
export module App {
export class SomeClass {
getName(): string {
return 'name';
}
}
export class OtherClass {
getName(): string {
return 'name';
}
}
}
Și acum îl putem importa în aceste trei moduri:
import * as app1 from "./test";
import app2 = require("./test");
import {App} from "./test";
Și putem consuma produse importate precum acesta:
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();
și apelează metoda pentru a o vedea în acțiune:
console.log(a1.getName())
console.log(a2.getName())
console.log(b1.getName())
console.log(b2.getName())
console.log(c1.getName())
console.log(c2.getName())
Partea originală încearcă să ajute la reducerea cantității de complexitate în utilizarea spațiului de nume
Piesă originală:
Aș sugera cu adevărat să verificați această Întrebări și Răspunsuri:
Cum folosesc namespace-urile cu module externe TypeScript?
Permiteți-mi să citez prima propoziție:
Nu utilizați „spații de nume” în modulele externe.
Nu face asta.
Serios. Oprește-te.
...
În acest caz, pur și simplu nu avem nevoie de module în interiorul fișierului test.ts. Acesta ar putea fi conținutul său ajustat al fișierului test.ts:
export class SomeClass
{
getName(): string
{
return 'name';
}
}
Citește mai mult aici
Export =
În exemplul anterior, când am folosit fiecare validator, fiecare modul a exportat doar o valoare. În cazuri ca acesta, este incomod să lucrăm cu aceste simboluri prin numele lor calificat, când un singur identificator ar fi la fel de eficient.
Sintaxa
export =specifică un singur obiect care este exportat din modul. Acesta poate fi o clasă, interfață, modul, funcție sau enum. Când este importat, simbolul exportat este utilizat direct și nu este calificat de niciun nume.
putem să-l consumăm mai târziu astfel:
import App = require('./test');
var sc: App.SomeClass = new App.SomeClass();
sc.getName();
Citește mai mult aici:
Încărcarea Modulului Opțional și Alte Scenarii Avansate de Încărcare
În unele cazuri, este posibil să doriți să încărcați un modul doar în anumite condiții. În TypeScript, putem folosi modelul prezentat mai jos pentru a implementa acest lucru și alte scenarii avansate de încărcare pentru a apela direct încărcătoarele de module fără a pierde siguranța tipurilor.
Compilatorul detectează dacă fiecare modul este utilizat în JavaScript-ul emis. Pentru modulele care sunt folosite doar ca parte a sistemului de tipuri, nu sunt emise apeluri require. Această eliminare a referințelor neutilizate este o bună optimizare a performanței și permite, de asemenea, încărcarea opțională a acelor module.
Ideea principală a modelului este că instrucțiunea import id=require('...') ne oferă acces la tipurile expuse de modulul extern. Încărcătorul de module este invocat (prin require) dinamic, așa cum este prezentat în blocurile if de mai jos. Aceasta valorifică optimizarea eliminării referințelor astfel încât modulul să fie încărcat doar atunci când este necesar. Pentru ca acest model să funcționeze, este important ca simbolul definit prin import să fie utilizat doar în poziții de tip (adică niciodată într-o poziție care ar fi emisă în JavaScript).
Răspunsul #2
Răspunsurile de mai sus sunt corecte. Dar doar în caz... Am avut aceeași eroare în VS Code. A trebuit să refac salvarea/recompilarea fișierului care provoca eroarea.
Răspunsul #3
Cum pot realiza asta?
Exemplul tău declară un modul intern TypeScript < 1.5, care acum se numește namespace. Vechea sintaxă module App {} este acum echivalentă cu namespace App {}. Ca rezultat, următorul cod funcționează:
// test.ts
export namespace App {
export class SomeClass {
getName(): string {
return 'name';
}
}
}
// main.ts
import { App } from './test';
var a = new App.SomeClass();
Spunând asta...
Încercați să evitați exportarea spațiilor de nume și, în schimb, să exportați module (care erau anterior numite module externe). Dacă este necesar, puteți folosi un spațiu de nume la import cu pattern-ul de import al spațiului de nume astfel:
// test.ts
export class SomeClass {
getName(): string {
return 'name';
}
}
// main.ts
import * as App from './test'; // namespace import pattern
var a = new App.SomeClass();
Răspuns #4
Pe lângă răspunsul lui A. Tim, există momente când nici asta nu funcționează, așa că trebuie să:
- Rescrie șirul de import, folosind intellisense. Uneori asta rezolvă problema
- Repornește VS Code
