¿Qué significa" resol resuelve a una entidad que no es módulo y no se puede importar usando esta construcción"?


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" resuelve a una entidad que no es módulo y no se puede importar usando esta construcción.

Y al intentar llamar fn()

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

¿Qué da?

Author: Ryan Cavanaugh, 2016-09-09

4 answers

Por qué no funciona

import * as MC from './MyClass';

Esta es la sintaxis ES6/ES2015-style import. El significado exacto de esto es "Toma el objeto de espacio de nombres module cargado desde ./MyClass y úsalo localmente como MC". Notablemente, el " module namespace object" consiste solo en un objeto plano con propiedades. Un objeto de módulo ES6 no puede ser invocado como una función o con new.

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

Lo que import usa * as X desde un módulo se define como que solo tiene propiedades. En CommonJS downleveled esto podría no ser completamente respetado, pero TypeScript le está diciendo cuál es el comportamiento definido por el estándar.

¿Qué funciona?

Necesitará usar la sintaxis de importación al 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.

Habría sido bueno usar la sintaxis de importación de ES6, pero ahora tengo que hacer esto import MC = require('./MyClass');? ¡Es tan 2013! ¡Patético! Pero el dolor es una parte normal de la programación. Por favor, salta a la quinta etapa en el modelo Kübler-Ross: Aceptación.

TypeScript aquí te dice que esto no funciona, porque no funciona. Hay hacks (añadiendo un namespace declaration to MyClass es una forma popular de pretender que esto funciona), y podrían funcionar hoy en día en su paquete de módulos de downleveling en particular (por ejemplo, rollup), 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 yo futuro, tratando de ejecutar en una implementación de módulo ES6 nativo de neato y encontrando que se ha configurado para un fallo mayor al tratando de usar la sintaxis ES6 para hacer algo que ES6 explícitamente no hace .

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

Tal vez tenga un cargador de módulos que "amablemente" crea exportaciones default cuando no existen. Quiero decir, la gente hace estándares por una razón, pero ignorar los estándares es divertido a veces y podemos pensar que eso es algo genial.

Change MyConsumer.ts a:

import A from './a';

Y especifique la línea de comandos allowSyntheticDefaultImports o la opción tsconfig.json.

Tenga en cuenta que allowSyntheticDefaultImports no cambia el comportamiento en tiempo de ejecución de su código. Es solo un indicador que indica a TypeScript que el cargador de módulos crea exportaciones default cuando no existen. No hará mágicamente que su código funcione en nodejs cuando no lo hacía antes.

 118
Author: Ryan Cavanaugh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-28 15:50:51

TypeScript 2.7 introduce el 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

Así que en tsconfig.json añade estas dos opciones:

{
    // 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';
 6
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-09 03:37:02

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

Mi forma de trabajar alrededor del problema sin modificar tsconfig.json (que puede ser problemático en algunos proyectos), he ido con simplemente deshabilitar la regla para oneline.

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

 2
Author: Shahar Hadas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-16 04:03:39

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

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

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

Esto terminó funcionando:

import debounce from 'debounce' 
 2
Author: NSjonas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-31 20:53:03