javascript - entre - Módulo de importación de mecanografiado es6 "El archivo no es un error de módulo"
typescript vs es6 (4)
Estoy usando typecript 1.6 con sintaxis de módulos es6.
Mis archivos son:
test.ts:
module App {
export class SomeClass {
getName(): string {
return ''name'';
}
}
}
main.ts:
import App from ''./test'';
var a = new App.SomeClass();
Cuando intento compilar el archivo
main.ts
me sale este error:
Error TS2306: el archivo ''test.ts'' no es un módulo.
¿Cómo puedo lograr eso?
¿Cómo puedo lograr eso?
Su ejemplo declara un
módulo interno
TypeScript <1.5, que ahora se denomina
namespace
.
La antigua sintaxis de la
module App {}
ahora es equivalente a la
namespace App {}
de
namespace App {}
.
Como resultado, lo siguiente funciona:
// test.ts
export namespace App {
export class SomeClass {
getName(): string {
return ''name'';
}
}
}
// main.ts
import { App } from ''./test'';
var a = new App.SomeClass();
Habiendo dicho eso...
Intente evitar exportar espacios de nombres y, en su lugar, exporte módulos (que anteriormente se denominaban módulos externos ). Si es necesario, puede usar un espacio de nombres en la importación con el patrón de importación del espacio de nombres como este:
// test.ts
export class SomeClass {
getName(): string {
return ''name'';
}
}
// main.ts
import * as App from ''./test''; // namespace import pattern
var a = new App.SomeClass();
Además de la respuesta de A. Tim, hay momentos en que incluso eso no funciona, por lo que debe:
- Reescribe la cadena de importación, usando el intellisense. A veces esto soluciona el problema
- Reiniciar VS Code
Las respuestas anteriores son correctas. Pero por si acaso ... Tengo el mismo error en VS Code. Tuve que volver a guardar / recompilar el archivo que arrojaba el error.
Extendido : para proporcionar más detalles basados en algunos comentarios
El error
Error TS2306: el archivo ''test.ts'' no es un módulo.
Proviene del hecho descrito aquí http://exploringjs.com/es6/ch_modules.html
17. módulos
Este capítulo explica cómo funcionan los módulos integrados en ECMAScript 6.
17.1 Descripción generalEn ECMAScript 6, los módulos se almacenan en archivos. Hay exactamente un módulo por archivo y un archivo por módulo. Tiene dos formas de exportar cosas desde un módulo. Estas dos formas se pueden mezclar, pero generalmente es mejor usarlas por separado.
17.1.1 Múltiples exportaciones con nombre
Puede haber múltiples exportaciones con nombre:
//------ 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 Exportación predeterminada única
Puede haber una única exportación predeterminada. Por ejemplo, una función:
//------ myFunc.js ------ export default function () { ··· } // no semicolon!
Según lo anterior, necesitamos la
export
, como parte del archivo
test.js.
Vamos a ajustar el contenido de esta manera:
// test.js - exporting es6
export module App {
export class SomeClass {
getName(): string {
return ''name'';
}
}
export class OtherClass {
getName(): string {
return ''name'';
}
}
}
Y ahora podemos importarlo de estas tres maneras:
import * as app1 from "./test";
import app2 = require("./test");
import {App} from "./test";
Y podemos consumir cosas importadas como esta:
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();
y llame al método para verlo en acción:
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 parte original trata de ayudar a reducir la cantidad de complejidad en el uso del espacio de nombres
Parte original:
Realmente recomendaría que revise estas preguntas y respuestas:
¿Cómo uso espacios de nombres con módulos externos TypeScript?
Permítanme citar la primera oración:
No utilice "espacios de nombres" en módulos externos.
No hagas esto.
Seriamente. Detener.
...
En este caso, simplemente no necesitamos
module
dentro de
test.ts
Este podría ser el contenido de
test.ts
ajustado:
export class SomeClass
{
getName(): string
{
return ''name'';
}
}
Leer más aquí
Exportar =
En el ejemplo anterior, cuando consumimos cada validador, cada módulo solo exportaba un valor. En casos como este, es engorroso trabajar con estos símbolos a través de su nombre calificado cuando un solo identificador funcionaría igual de bien.
La sintaxis
export =
especifica un único objeto que se exporta desde el módulo . Puede ser una clase, interfaz, módulo, función o enumeración. Cuando se importa, el símbolo exportado se consume directamente y no está calificado por ningún nombre.
luego podemos consumirlo así:
import App = require(''./test'');
var sc: App.SomeClass = new App.SomeClass();
sc.getName();
Leer más aquí:
Módulo opcional de carga y otros escenarios de carga avanzada
En algunos casos, es posible que solo desee cargar un módulo bajo ciertas condiciones. En TypeScript, podemos usar el patrón que se muestra a continuación para implementar este y otros escenarios de carga avanzados para invocar directamente los cargadores de módulos sin perder la seguridad de los tipos.
El compilador detecta si cada módulo se usa en el JavaScript emitido. Para los módulos que solo se usan como parte del sistema de tipos, no se emiten llamadas obligatorias. Esta selección de referencias no utilizadas es una buena optimización del rendimiento y también permite la carga opcional de esos módulos.
La idea central del patrón es que la instrucción import id = require (''...'') nos da acceso a los tipos expuestos por el módulo externo. El cargador de módulos se invoca (a través de require) dinámicamente, como se muestra en los bloques if a continuación. Esto aprovecha la optimización de selección de referencias para que el módulo solo se cargue cuando sea necesario. Para que este patrón funcione, es importante que el símbolo definido mediante importación solo se use en posiciones de tipo (es decir, nunca en una posición que se emitiría en JavaScript).