Cosa significa “… si risolve in un’ quadro non modulo e non può essere importato usando questo costrutto” significa?

Ho alcuni file 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(); 

Questo mi dà errori quando provo a usare new

Il modulo “MyClass” si risolve in un’ quadro non modulo e non può essere importato utilizzando questo costrutto.

e quando si prova a chiamare fn()

Imansible richiamare un’espressione il cui tipo non ha una firma di chiamata.

Cosa dà?

Perché non funziona

 import * as MC from './MyClass'; 

Questa è la syntax di import stile ES6 / ES2015. Il significato esatto di ciò è “Prendi l’ object dello spazio dei nomi del modulo caricato da ./MyClass e ./MyClass localmente come MC “. In particolare, l ‘” object dello spazio dei nomi del modulo” consiste solo di un object semplice con proprietà. Un object modulo ES6 non può essere invocato come una funzione o con una new .

Per dirlo ancora: un object dello spazio dei nomi del modulo ES6 non può essere invocato come una funzione o con una new .

La cosa che si import usando * as X da un modulo è definita per avere solo proprietà. In CommonJS di livello inferiore, questo potrebbe non essere pienamente rispettato, ma TypeScript sta dicendo quale sia il comportamento definito dallo standard.

Cosa funziona?

Dovrai utilizzare la syntax di importazione in stile CommonJS per utilizzare questo modulo:

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

Se controlli entrambi i moduli, puoi invece utilizzare l’ export default :

MyClass.ts

 export default class MyClass { constructor() { } } 

MyConsumer.ts

 import MC from './MyClass'; 

Sono triste per questo; Le regole sono stupide.

Sarebbe stato bello usare la syntax di importazione ES6, ma ora devo fare questa import MC = require('./MyClass'); cosa? È così il 2013! Noioso! Ma il dolore è una parte normale della programmazione. Per favore, salta alla quinta tappa del modello Kübler-Ross: Accettazione.

TypeScript qui dice che questo non funziona, perché non funziona. Ci sono hack (aggiungere una dichiarazione di namespace a MyClass è un modo popolare per far finta che funzioni), e potrebbero funzionare oggi nel tuo particolare bundler di moduli (ad es. Rollup), ma questo è illusorio. Non ci sono ancora implementazioni di moduli ES6 in natura, ma non sarà vero per sempre.

Immaginate la vostra auto futura, provando a eseguire un’implementazione nativa del modulo ES6 nativo e scoprendo che vi siete prefissati per un grave errore cercando di utilizzare la syntax ES6 per fare qualcosa che ES6 non fa esplicitamente .

Voglio approfittare del mio caricatore di moduli non standard

Forse hai un caricatore di moduli che crea “utili” le esportazioni di default quando non ce ne sono. Voglio dire, le persone fanno degli standard per una ragione, ma a volte ignorare gli standard è divertente e possiamo pensare che sia una cosa interessante da fare.

Cambia MyConsumer.ts in:

 import A from './a'; 

E specificare l’ allowSyntheticDefaultImports della allowSyntheticDefaultImports comando tsconfig.json o tsconfig.json .

Si noti che allowSyntheticDefaultImports non modifica affatto il comportamento di runtime del proprio codice. È solo un flag che indica a TypeScript che il tuo caricatore di moduli crea esportazioni default quando non esistono. Non magicamente farà funzionare il tuo codice in nodejs quando non lo ha fatto prima.

Ho ricevuto questo errore durante il tentativo di includere un pacchetto di debug npm nel mio progetto.

Quando ho provato la soluzione accettata sopra ho ottenuto un’eccezione:

L’assegnazione dell’importazione non può essere utilizzata durante il targeting dei moduli ECMAScript. Prendi in considerazione l’uso di “import * come ns da” mod “”, “import {a} da” mod “”, “import d da” mod “” o un altro formato di modulo.

Questo ha finito per funzionare:

 import debounce from 'debounce' 

TypeScript 2.7 introduce il supporto emettendo nuovi metodi di supporto: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-form- commonjs-modules-con — esmoduleinterop

Quindi in tsconfig.json aggiungi queste due impostazioni:

 { // 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 } 

E ora puoi usare:

 import MyClass from './MyClass'; 

Aggiungendo i miei 2 centesimi qui in caso qualcun altro abbia questo problema.

Il mio modo di aggirare il problema senza modificare tsconfig.json (che può essere problematico in alcuni progetti), sono andato semplicemente disabilitando la regola per oneline.

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