क्या करता है "... एक गैर-मॉड्यूल इकाई का समाधान करता है और इस निर्माण का उपयोग करके आयात नहीं किया जा सकता है" मतलब है?


93

मेरे पास कुछ टाइपस्क्रिप्ट फाइलें हैं:

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

यह मुझे त्रुटियों का उपयोग करते समय देता है new

मॉड्यूल "MyClass" एक गैर-मॉड्यूल इकाई का समाधान करता है और इस निर्माण का उपयोग करके आयात नहीं किया जा सकता है।

और जब फोन करने की कोशिश कर रहा हो fn()

एक अभिव्यक्ति को टाइप नहीं कर सकते हैं जिसके प्रकार में कॉल हस्ताक्षर की कमी है।

क्या देता है?


2
उत्तर साझा करने के लिए धन्यवाद। मैं javascriptप्राथमिक टैग के रूप में हटाने और छोड़ने का सुझाव दूंगा ecmascript-6, क्योंकि यहां प्राथमिक टैग है typescript। प्रश्न गलत तरीके से मानता है कि export =(एक TS सुविधा) के साथ जोड़ा जा सकता है import ... from, जबकि इसे साथ जोड़ा जाना चाहिएimport = । यह मूल रूप से ES6 मॉड्यूल आयात / निर्यात बनाम CJS / AMD है।
एस्टुस फ्लास्क

जवाबों:


156

यह काम क्यों नहीं करता है

import * as MC from './MyClass';

यह ES6 / ES2015-शैली importवाक्यविन्यास है। इसका सटीक अर्थ "मॉड्यूल नेमस्पेस ऑब्जेक्ट से लोड किया गया है ./MyClassऔर इसे स्थानीय रूप से उपयोग करना है MC"। विशेष रूप से, "मॉड्यूल नेमस्पेस ऑब्जेक्ट " में गुणों के साथ केवल एक सादे वस्तु होती है। एक ES6 मॉड्यूल ऑब्जेक्ट को फ़ंक्शन के साथ या उसके साथ नहीं लगाया जा सकता है new

इसे फिर से कहने के लिए: एक ईएस 6 मॉड्यूल नेमस्पेस ऑब्जेक्ट को एक फ़ंक्शन के रूप में या साथ नहीं लगाया जा सकता है new

किसी मॉड्यूल से आपके द्वारा importउपयोग की जाने वाली चीज़ * as Xको केवल गुणों के लिए परिभाषित किया गया है। खराब कॉमनजेएस में यह पूरी तरह से सम्मानित नहीं हो सकता है, लेकिन टाइपस्क्रिप्ट आपको बता रहा है कि मानक द्वारा निर्धारित व्यवहार क्या है।

क्या काम करता है?

आपको इस मॉड्यूल का उपयोग करने के लिए CommonJS- शैली आयात सिंटैक्स का उपयोग करना होगा:

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

यदि आप दोनों मॉड्यूल को नियंत्रित करते हैं, तो आप export defaultइसके बजाय उपयोग कर सकते हैं :

MyClass.ts

export default class MyClass {
  constructor() {
  }
}

MyConsumer.ts

import MC from './MyClass';

मैं इस बारे में दुखी हूँ; नियम गूंगे हैं।

ES6 आयात सिंटैक्स का उपयोग करना अच्छा होता, लेकिन अब मुझे यह import MC = require('./MyClass');काम करना है? यह 2013 की बात है! लंगड़ा! लेकिन दुख प्रोग्रामिंग का एक सामान्य हिस्सा है। कृपया Kübler-Ross मॉडल: स्वीकृति में चरण पांच पर जाएं।

यहां टाइपस्क्रिप्ट आपको बता रहा है कि यह काम नहीं करता है, क्योंकि यह काम नहीं करता है। हैक होते हैं ( इस कार्य को प्रदर्शित करने के लिए एक namespaceघोषणा को जोड़ना एक MyClassलोकप्रिय तरीका है), और वे आज आपके विशेष डाउनलिवलिंग मॉड्यूल बंडलर (जैसे रोलअप) में काम कर सकते हैं, लेकिन यह भ्रमपूर्ण है। वहाँ अभी तक जंगली में कोई ES6 मॉड्यूल कार्यान्वयन नहीं हैं, लेकिन यह हमेशा के लिए सच नहीं होगा।

अपने भविष्य के स्वयं के चित्र, एक साफ-सुथरे देशी ईएस 6 मॉड्यूल के क्रियान्वयन पर चलने की कोशिश करना और यह पता लगाना कि आपने ईएस 6 सिंटैक्स का उपयोग करने की कोशिश करके खुद को बड़ी विफलता के लिए तैयार किया है, जो ईएस 6 स्पष्ट रूप से नहीं करता है

मैं अपने गैर-मानक मॉड्यूल लोडर का लाभ उठाना चाहता हूं

हो सकता है कि आपके पास एक मॉड्यूल लोडर है जो "मददगार" defaultनिर्यात करता है जब कोई भी मौजूद नहीं होता है। मेरा मतलब है, लोग एक कारण के लिए मानक बनाते हैं, लेकिन मानकों की अनदेखी करना कभी-कभी मज़ेदार होता है और हम सोच सकते हैं कि यह एक अच्छी बात है।

MyConsumer.ts को इसमें बदलें :

import A from './a';

और allowSyntheticDefaultImportsकमांड-लाइन या tsconfig.jsonविकल्प निर्दिष्ट करें ।

ध्यान दें कि allowSyntheticDefaultImportsआपके कोड का रनटाइम व्यवहार बिल्कुल भी नहीं बदलता है। यह सिर्फ एक ध्वज है जो टाइपस्क्रिप्ट को बताता है कि आपका मॉड्यूल लोडर defaultकोई भी मौजूद होने पर निर्यात करता है। यह जादुई रूप से आपके कोड को नोडज में काम नहीं करेगा जब यह पहले नहीं था।


क्या आमजन शैली को एक आम लक्ष्य की आवश्यकता नहीं है? क्या यह कार्य करने का कोई तरीका है जब आप es6 / es2015 को लक्षित कर रहे हैं?
स्टीव बुज़ोनस

आप इसे ES6 को लक्षित करने के लिए काम नहीं कर सकते क्योंकि यह ES6 में काम नहीं करता है ...
रयान कैवानुघ

क्या मैं यह समझने में सही हूं कि अगर मैं ES2015 मॉड्यूल को लक्षित कर रहा हूं, तो कॉमनजस मॉड्यूल को संदर्भित करने का कोई तरीका नहीं है export = MyClass? मेरा एकमात्र विकल्प यह है कि मैं अपने मॉड्यूल को सेट करूं commonjsऔर आधुनिक ES का उपयोग न करके दुनिया को एक बदतर जगह बनाऊं?
मीका झोल्टू

6
में 2.7 रिलीज नोट्स , के तहत --esModuleInterop, यह कहते हैं, "हम अत्यधिक यह दोनों नए और मौजूदा परियोजनाओं के लिए आवेदन करने की सलाह देते हैं"। मेरी राय में, इस उत्तर (और उस लिंक में FAQ प्रविष्टि / नीतिDefinitelyTyped ) को नए रुख को प्रतिबिंबित करने के लिए संशोधित किया जाना चाहिए।
एलेक मेव

1
तो बहुत सासी।
jmealy

25

टाइपस्क्रिप्ट 2.7 नए सहायक तरीकों को छोड़ कर समर्थन का परिचय देता है: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-form-form commonjs-मॉड्यूल-साथ --- esmoduleinterop

तो tsconfig.json में ये दो सेटिंग्स जोड़ें:

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

और अब आप उपयोग कर सकते हैं:

import MyClass from './MyClass';

उपयोग करने के बजाय esModuleInteropमैंने उपयोग करने resolveJsonModuleके आपके अन्य सुझाव का उपयोग किया allowSyntheticDefaultImportsऔर इसने मेरे लिए काम किया।
एडगर क्विंटो

6

यहाँ मेरे 2 सेंट जोड़ना किसी और को यह मुद्दा है।

इस मुद्दे को संशोधित किए बिना काम करने का मेरा तरीका tsconfig.json(जो कुछ परियोजनाओं में समस्याग्रस्त हो सकता है), मैं ऑनलाइन के लिए नियम को अक्षम करने के साथ चला गया हूं।

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


5

मुझे यह त्रुटि तब मिली जब मैं अपने प्रोजेक्ट में एक npm डेबिट पैकेज को शामिल करने की कोशिश कर रहा था।

जब मैंने उपरोक्त समाधान की कोशिश की तो मुझे एक अपवाद मिला:

ECMAScript मॉड्यूल को लक्षित करते समय आयात असाइनमेंट का उपयोग नहीं किया जा सकता है। "Mod" से ns के रूप में 'import * के रूप में उपयोग करने पर विचार करें,' 'mod "से' a} आयात करें," mod "से 'd से आयात करें', या इसके बजाय किसी अन्य मॉड्यूल प्रारूप में।

यह काम खत्म हो गया:

import debounce from 'debounce' 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.