not namespace typescript ecmascript-6 es6-modules

typescript - namespace - ¿Qué significa "... se resuelve en una entidad que no es un módulo y no se puede importar utilizando esta construcción"?



typescript import (4)

Tengo algunos archivos TypeScript:

MyClass.ts

class MyClass { constructor() { } } export = MyClass;

MyFunc.ts

function fn() { return 0; } export = fn;

MyConsumer.ts

import * as MC from ''./MyClass''; import * as fn from ''./MyFunc''; fn();

Esto me da errores al intentar usar new

El módulo "MyClass" se resuelve en una entidad que no es un módulo y no se puede importar utilizando esta construcción.

y al intentar llamar a fn()

No se puede invocar una expresión cuyo tipo carece de una firma de llamada.

¿Lo que da?


Por que no funciona

import * as MC from ''./MyClass'';

Esta es la sintaxis de import estilo ES6 / ES2015. El significado exacto de esto es "Tome el objeto del espacio de nombres del módulo cargado desde ./MyClass y utilícelo localmente como MC ". En particular, el " objeto de espacio de nombres del módulo" consiste solo en un objeto plano con propiedades. Un objeto de módulo ES6 no se puede invocar como una función o con new .

Para decirlo de nuevo: un objeto de espacio de nombres del módulo ES6 no se puede invocar como una función o con new .

Lo que import utilizando * as X desde un módulo se define para tener solo propiedades. En CommonJS de nivel inferior, esto podría no respetarse completamente, pero TypeScript le dice cuál es el comportamiento definido por el estándar.

Que funciona

Deberá usar la sintaxis de importación de estilo CommonJS para usar este módulo:

import MC = require(''./MyClass'');

Si controla ambos módulos, puede usar export default lugar:

MyClass.ts

export default class MyClass { constructor() { } }

MyConsumer.ts

import MC from ''./MyClass'';

Estoy triste por esto; Las reglas son tontas.

Hubiera sido bueno usar la sintaxis de importación ES6, pero ahora tengo que hacer esta import MC = require(''./MyClass''); ¿cosa? ¡Es tan 2013! ¡Cojo! Pero el dolor es una parte normal de la programación. Vaya a la etapa cinco en el modelo de Kübler-Ross: aceptación.

TypeScript aquí te dice que esto no funciona, porque no funciona. Hay hacks (agregar una declaración de namespace a MyClass es una forma popular de fingir que esto funciona), y podrían funcionar hoy en su paquete de módulo de nivel inferior particular (por ejemplo, paquete acumulativo), pero esto es ilusorio. Todavía no hay implementaciones de módulos ES6 en la naturaleza, pero eso no será cierto para siempre.

Imagínese su futuro, tratando de ejecutar una implementación de módulo ES6 neato nativo y descubriendo que se ha preparado para una falla importante al tratar de usar la sintaxis de ES6 para hacer algo que ES6 explícitamente no hace .

Quiero aprovechar mi cargador de módulos no estándar

Quizás tenga un cargador de módulos que "útilmente" cree exportaciones default cuando no exista ninguna. Quiero decir, la gente hace estándares por una razón, pero ignorarlos es divertido a veces y podemos pensar que es algo genial.

Cambie MyConsumer.ts a:

import A from ''./a'';

Y especifique la allowSyntheticDefaultImports comandos tsconfig.json o la opción tsconfig.json .

Tenga en cuenta que allowSyntheticDefaultImports no cambia en absoluto el comportamiento de tiempo de ejecución de su código. Es solo una bandera que le dice a TypeScript que su cargador de módulos crea exportaciones default cuando no existe ninguna. No hará que su código funcione mágicamente en nodejs cuando no lo hacía antes.


Agregar mis 2 centavos aquí en caso de que alguien más tenga este problema.

Mi forma de tsconfig.json el problema sin modificar tsconfig.json (que puede ser problemático en algunos proyectos), simplemente he deshabilitado la regla en línea.

import MC = require(''./MyClass''); // tslint:disable-line


Recibí este error al intentar incluir un paquete de rebote npm en mi proyecto.

Cuando probé la solución aceptada arriba, obtuve una excepción:

La asignación de importación no se puede utilizar cuando se dirigen a módulos ECMAScript. Considere usar ''import * como ns de "mod"'', ''import {a} de "mod"'', ''import d de "mod"'' u otro formato de módulo.

Esto terminó funcionando:

import debounce from ''debounce''


TypeScript 2.7 introduce soporte mediante la emisión de nuevos métodos auxiliares: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-form-commonjs-modules-with---esmoduleinterop

Entonces, en tsconfig.json, agregue estas dos configuraciones:

{ // Enable support for importing CommonJS modules targeting es6 modules "esModuleInterop": true, // When using above interop will get missing default export error from type check since // modules use "export =" instead of "export default", enable this to ignore errors. "allowSyntheticDefaultImports": true }

Y ahora puedes usar:

import MyClass from ''./MyClass'';