web-dev-qa-db-fra.com

Type d'importation es6 du module "Le fichier n'est pas une erreur de module"

J'utilise TypeScript 1.6 avec la syntaxe des modules es6.

Mes fichiers sont:

test.ts:

module App {
  export class SomeClass {
    getName(): string {
      return 'name';
    }
  }
}

main.ts:

import App from './test';

var a = new App.SomeClass();

Lorsque j'essaie de compiler le fichier main.ts, le message d'erreur suivant s'affiche:

Erreur TS2306: le fichier 'test.ts' n'est pas un module.

Comment puis-je accomplir cela?

89
Bazinga

Etendu - pour fournir plus de détails à partir de certains commentaires

L'erreur

Erreur TS2306: Le fichier 'test.ts' n'est pas un module.

Vient du fait décrit ici http://exploringjs.com/es6/ch_modules.html

17. modules

Ce chapitre explique le fonctionnement des modules intégrés dans ECMAScript 6.

17.1 Aperçu

Dans ECMAScript 6, les modules sont stockés dans des fichiers. Il y a exactement un module par fichier et un fichier par module. Vous avez deux façons d'exporter des éléments d'un module. Ces deux méthodes peuvent être mélangées, mais il est généralement préférable de les utiliser séparément.

17.1.1 Exportations nommées multiples

Il peut y avoir plusieurs exportations nommées:

_//------ 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 Exportation par défaut unique

Il peut y avoir une seule exportation par défaut. Par exemple, une fonction:

_//------ myFunc.js ------
export default function () { ··· } // no semicolon!
_

Sur la base de ce qui précède, nous avons besoin de la export, en tant que partie du test.js fichier. Réglons le contenu comme ceci:

_// test.js - exporting es6
export module App {
  export class SomeClass {
    getName(): string {
      return 'name';
    }
  }
  export class OtherClass {
    getName(): string {
      return 'name';
    }
  }
}
_

Et maintenant, nous pouvons l’importer avec ces trois méthodes:

_import * as app1 from "./test";
import app2 = require("./test");
import {App} from "./test";
_

Et nous pouvons consommer des choses importées comme ceci:

_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();
_

et appelez la méthode pour la voir en action:

_console.log(a1.getName())
console.log(a2.getName())
console.log(b1.getName())
console.log(b2.getName())
console.log(c1.getName())
console.log(c2.getName())
_

La partie d'origine tente de réduire la complexité d'utilisation de l'espace de noms

Partie d'origine:

Je suggérerais fortement de vérifier cette Q & A:

Comment utiliser les espaces de noms avec les modules externes TypeScript?

Permettez-moi de citer la première phrase:

N'utilisez pas d '"espaces de noms" dans des modules externes.

Ne fais pas ça.

Sérieusement. Arrêtez.

...

Dans ce cas, nous n’avons tout simplement pas besoin de module à l’intérieur de _test.ts_. Cela pourrait être le contenu de celui-ci ajusté test.ts:

_export class SomeClass
{
    getName(): string
    {
        return 'name';
    }
}
_

Lire la suite ici

Export =

Dans l'exemple précédent, lorsque nous utilisions chaque validateur, chaque module n'exportait qu'une valeur. Dans de tels cas, il est fastidieux de manipuler ces symboles par leur nom qualifié alors qu’un seul identifiant conviendrait tout aussi bien.

La syntaxe _export =_ spécifie un seul objet exporté du module . Cela peut être une classe, une interface, un module, une fonction ou une énumération. Lorsqu'il est importé, le symbole exporté est consommé directement et n'est qualifié par aucun nom.

nous pouvons le consommer plus tard comme ceci:

_import App = require('./test');

var sc: App.SomeClass = new App.SomeClass();

sc.getName();
_

Lire la suite ici:

Chargement de module optionnel et autres scénarios de chargement avancés

Dans certains cas, vous souhaiterez peut-être charger un module uniquement dans certaines conditions. Dans TypeScript, nous pouvons utiliser le modèle présenté ci-dessous pour implémenter ce scénario et d'autres scénarios de chargement avancés afin d'appeler directement les chargeurs de module sans perdre la sécurité du type.

Le compilateur détecte si chaque module est utilisé dans le code JavaScript émis. Pour les modules utilisés uniquement dans le cadre du système de types, aucun appel requis n'est émis. Cette élimination des références inutilisées constitue une bonne optimisation des performances et permet également le chargement facultatif de ces modules.

L'idée centrale du modèle est que l'instruction import id = require ('...') nous donne accès aux types exposés par le module externe. Le chargeur de module est invoqué (via require) dynamiquement, comme indiqué dans les blocs if ci-dessous. Ceci tire parti de l'optimisation de la sélection des références afin que le module ne soit chargé que lorsque cela est nécessaire. Pour que ce modèle fonctionne, il est important que le symbole défini via l'importation ne soit utilisé que dans les positions de type (c'est-à-dire, jamais dans une position qui serait émise dans JavaScript).

105
Radim Köhler

Comment puis-je accomplir cela?

Votre exemple déclare un module interne TypeScript <1.5 , appelé désormais un espace de noms . L'ancienne syntaxe module App {} est maintenant équivalente à namespace App {}. En conséquence, les travaux suivants:

// test.ts
export namespace App {
    export class SomeClass {
        getName(): string {
            return 'name';
        }
    }
}

// main.ts
import { App } from './test';
var a = new App.SomeClass();

Cela étant dit...

Essayez d'éviter d'exporter des espaces de noms et exportez plutôt des modules (qui s'appelaient auparavant des modules externes ). Si besoin est, vous pouvez utiliser un espace de noms lors de l'importation avec le modèle d'importation d'espace comme ceci:

// test.ts
export class SomeClass {
    getName(): string {
        return 'name';
    }
}

// main.ts
import * as App from './test'; // namespace import pattern
var a = new App.SomeClass();
9
Shaun Luttin

Les réponses ci-dessus sont correctes. Mais juste au cas où ... Vous avez la même erreur dans VS Code. A dû ré-enregistrer/recompiler le fichier qui jetait une erreur.

8
A. Tim

En plus de réponse de A. Tim il y a des moments où même cela ne fonctionne pas, vous devez donc:

  1. Réécrivez la chaîne d'importation en utilisant l'intellisense. Parfois, cela résout le problème
  2. Redémarrer le code VS
2
ZenVentzi