टाइपस्क्रिप्ट es6 आयात मॉड्यूल "फ़ाइल एक मॉड्यूल त्रुटि नहीं है"


127

मैं es6 मॉड्यूल सिंटैक्स के साथ टाइपस्क्रिप्ट 1.6 का उपयोग कर रहा हूं।

मेरी फाइलें हैं:

test.ts:

module App {
  export class SomeClass {
    getName(): string {
      return 'name';
    }
  }
}

main.ts:

import App from './test';

var a = new App.SomeClass();

जब मैं main.tsफ़ाइल को संकलित करने की कोशिश कर रहा हूँ तो मुझे यह त्रुटि मिलती है:

TS2306 त्रुटि: फ़ाइल 'test.ts' एक मॉड्यूल नहीं है।

मैं इसे कैसे पूरा कर सकता हूं?


मेरे पास यह मुद्दा था, मेरे पास क्लास में कंस्ट्रक्टर नहीं था, एक जोड़ा और समस्या दूर हो गई
dorriz

जवाबों:


139

विस्तारित - कुछ टिप्पणियों के आधार पर अधिक विवरण प्रदान करने के लिए

त्रुटि

TS2306 त्रुटि: फ़ाइल 'test.ts' एक मॉड्यूल नहीं है।

यहाँ वर्णित तथ्य से आता है http://exploringjs.com/es6/ch_modules.html

17. मॉड्यूल

यह अध्याय बताता है कि ECMAScript 6 में अंतर्निहित मॉड्यूल कैसे काम करते हैं।

17.1 अवलोकन

ECMAScript 6 में, मॉड्यूल फाइलों में संग्रहीत होते हैं। प्रति फ़ाइल एक मॉड्यूल और प्रति मॉड्यूल एक फ़ाइल है। आपके पास मॉड्यूल से चीजों को निर्यात करने के दो तरीके हैं। इन दो तरीकों को मिश्रित किया जा सकता है, लेकिन आमतौर पर उन्हें अलग से उपयोग करना बेहतर होता है।

17.1.1 एकाधिक नामित निर्यात

कई नामित निर्यात हो सकते हैं:

//------ 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 एकल डिफ़ॉल्ट निर्यात

एकल डिफ़ॉल्ट निर्यात हो सकता है। उदाहरण के लिए, एक समारोह:

//------ myFunc.js ------
export default function () { ··· } // no semicolon!

उपरोक्त के आधार पर हमें test.js फ़ाइल के exportएक भाग के रूप में , की आवश्यकता है । आइए इस की सामग्री को इस तरह समायोजित करें:

// test.js - exporting es6
export module App {
  export class SomeClass {
    getName(): string {
      return 'name';
    }
  }
  export class OtherClass {
    getName(): string {
      return 'name';
    }
  }
}

और अब हम इसे इन तरीकों से आयात कर सकते हैं:

import * as app1 from "./test";
import app2 = require("./test");
import {App} from "./test";

और हम इस तरह आयातित सामान का उपभोग कर सकते हैं:

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

और इसे कार्रवाई में देखने के लिए विधि को कॉल करें:

console.log(a1.getName())
console.log(a2.getName())
console.log(b1.getName())
console.log(b2.getName())
console.log(c1.getName())
console.log(c2.getName())

मूल भाग नेमस्पेस के उपयोग में जटिलता की मात्रा को कम करने में मदद करने की कोशिश कर रहा है

मूल भाग:

मैं वास्तव में दृढ़ता से इस प्रश्नोत्तर की जाँच करने का सुझाव दूंगा:

मैं टाइपस्क्रिप्ट बाहरी मॉड्यूल के साथ नामस्थान का उपयोग कैसे करूं?

मुझे पहले वाक्य का हवाला देते हैं:

बाहरी मॉड्यूल में "नामस्थान" का उपयोग न करें।

यह मत करो।

गंभीरता से। रूक जा।

...

इस मामले में, हमें केवल moduleअंदर की आवश्यकता नहीं है test.ts। यह समायोजित की गई सामग्री हो सकती है test.ts:

export class SomeClass
{
    getName(): string
    {
        return 'name';
    }
}

यहाँ और पढ़ें

निर्यात =

पिछले उदाहरण में, जब हमने प्रत्येक सत्यापनकर्ता का उपभोग किया, तो प्रत्येक मॉड्यूल ने केवल एक मूल्य का निर्यात किया। इस तरह के मामलों में, इन प्रतीकों के साथ उनके योग्य नाम के माध्यम से काम करना बोझिल होता है जब एक एकल पहचानकर्ता ऐसा ही करेगा।

export =वाक्य रचना को निर्दिष्ट करता है एक वस्तु है कि मॉड्यूल से निर्यात किया जाता है । यह एक वर्ग, इंटरफ़ेस, मॉड्यूल, फ़ंक्शन, या एनम हो सकता है। जब आयात किया जाता है, तो निर्यात किए गए प्रतीक को सीधे उपभोग किया जाता है और किसी भी नाम से योग्य नहीं होता है।

हम बाद में इसे इस तरह से उपभोग कर सकते हैं:

import App = require('./test');

var sc: App.SomeClass = new App.SomeClass();

sc.getName();

यहाँ और पढ़ें:

वैकल्पिक मॉड्यूल लोड हो रहा है और अन्य उन्नत लोड हो रहा है परिदृश्य

कुछ मामलों में, आप केवल कुछ शर्तों के तहत एक मॉड्यूल लोड करना चाह सकते हैं। टाइपस्क्रिप्ट में, हम इस प्रकार और अन्य उन्नत लोडिंग परिदृश्यों को लागू करने के लिए नीचे दिखाए गए पैटर्न का उपयोग कर सकते हैं, सीधे टाइपिंग सुरक्षा को खोने के बिना मॉड्यूल लोडर को लागू करने के लिए।

संकलक पता लगाता है कि क्या प्रत्येक मॉड्यूल उत्सर्जित जावास्क्रिप्ट में उपयोग किया जाता है। उन मॉड्यूलों के लिए जिन्हें केवल टाइप सिस्टम के हिस्से के रूप में उपयोग किया जाता है, किसी भी कॉल की आवश्यकता नहीं होती है। अप्रयुक्त संदर्भों का यह पुलिंग एक अच्छा प्रदर्शन अनुकूलन है, और उन मॉड्यूल के वैकल्पिक लोडिंग के लिए भी अनुमति देता है।

पैटर्न का मुख्य विचार यह है कि आयात आईडी = आवश्यकता ('...') विवरण हमें बाहरी मॉड्यूल द्वारा उजागर किए गए प्रकारों तक पहुंच प्रदान करता है। मॉड्यूल लोडर को गतिशील रूप से (आवश्यकता के माध्यम से) लागू किया जाता है, जैसा कि नीचे के ब्लॉक में दिखाया गया है। यह रेफरेंस-कुलिंग ऑप्टिमाइज़ेशन का लाभ उठाता है ताकि मॉड्यूल केवल जरूरत पड़ने पर ही लोड हो। काम करने के लिए इस पैटर्न के लिए, यह महत्वपूर्ण है कि आयात के माध्यम से परिभाषित प्रतीक का उपयोग केवल प्रकार के पदों में किया जाता है (अर्थात कभी भी ऐसी स्थिति में जिसे जावास्क्रिप्ट में उत्सर्जित नहीं किया जाएगा)।


1
लेकिन यह: आयात ऐप = आवश्यकता ('./ परीक्षण'); es6 मॉड्यूल का सिंटैक्स नहीं है। यह सामान्य js है। क्या मैं इसे es6 मॉड्यूल सिंटैक्स के साथ कर सकता हूँ?
बेज़िंगा

@JsIsAwesome आप JS मॉड्यूल को टाइपस्क्रिप्ट मॉड्यूल के साथ मिलाने का प्रयास कर रहे हैं। आपको एक या दूसरे का उपयोग करने की आवश्यकता है, दोनों का मिश्रण नहीं।
जेजे

यह उत्तर ES6 वाक्य
phiresky

@phiresky, आपका क्या मतलब है?
रेडिम कोहलर

1
धन्यवाद, यह बहुत अच्छा है।
phiresky

24

उपरोक्त उत्तर सही हैं। लेकिन सिर्फ मामले में ... वीएस कोड में एक ही त्रुटि है। फ़ाइल को फिर से सहेजना / पुन: सहेजना था जो त्रुटि फेंक रहा था।


3
इसने मेरे लिए काम किया। मैंने बस एक अर्ध-उपनिवेश को हटा दिया, इसे फिर से जोड़ा और फ़ाइल को फिर से सहेजा, और फिर वेबपैक चलाने का काम किया। जीवित रहने के लिए महान समय।
रे होगन

1
मैं वेबस्टॉर्म का उपयोग कर रहा हूं और महसूस नहीं किया कि फाइलें वीएस कोड में स्वचालित रूप से सहेजी नहीं गई हैं। इस जवाब ने मुझे बहुत दर्द से बचाया, धन्यवाद।
cib

वीएस कोड में ऑटो सेव के लिए सेटिंग है। मैं इसका उपयोग नहीं करता क्योंकि वीएस कोड पहले से ही बिना सहेजे फाइलों का बैकअप लेता है और मैं हमेशा गिट का उपयोग नहीं करता।
जूल

13

मैं इसे कैसे पूरा कर सकता हूं?

आपका उदाहरण एक टाइपस्क्रिप्ट <1.5 आंतरिक मॉड्यूल घोषित करता है , जिसे अब नामस्थान कहा जाता है । पुराना module App {}सिंटेक्स अब इसके बराबर है namespace App {}। परिणामस्वरूप, निम्नलिखित कार्य करता है:

// test.ts
export namespace App {
    export class SomeClass {
        getName(): string {
            return 'name';
        }
    }
}

// main.ts
import { App } from './test';
var a = new App.SomeClass();

ऐसा कहे जाने के बाद...

नाम स्थान और निर्यात मॉड्यूल (जिसे पहले बाहरी मॉड्यूल कहा जाता था ) के निर्यात से बचने की कोशिश करें । अगर जरूरत हो तो आप इस तरह नामस्थान आयात पैटर्न के साथ आयात पर एक नाम स्थान का उपयोग कर सकते हैं :

// test.ts
export class SomeClass {
    getName(): string {
        return 'name';
    }
}

// main.ts
import * as App from './test'; // namespace import pattern
var a = new App.SomeClass();

1
यह अभी भी एक अच्छा अभ्यास है? इस उत्तर के अनुसार ( stackoverflow.com/a/35706271/2021224 ), इस तरह से एक फ़ंक्शन या वर्ग को आयात करने का प्रयास करना और फिर इसे लागू करना - "ES6 कल्पना के अनुसार अवैध है"।
एंड्री प्रोखोरोव

2

के अलावा ए टिम जवाब वहाँ ताकि आप की जरूरत है, जब भी वह काम नहीं करता समय है:

  1. इंटैलिजेंस का उपयोग करके आयात स्ट्रिंग को फिर से लिखें। कभी-कभी यह समस्या ठीक करता है
  2. वीएस कोड को पुनरारंभ करें

1
स्टैक्ब्लिट्ज़ के लिए समान - recompiled फ़ाइल जो मॉड्यूल को आयात करती है और सभी ठीक काम करती है, चीयर्स
Godblessstrawberry

मुझे भी यह अनुभव हुआ जब मेरा कोड सही प्रारूपित नहीं था। VSCode ने मेरी कॉपी + पेस्ट क्लास कोड का इंडेंट किया जब मैं अपनी कक्षाओं को अपनी फाइलों में विभाजित कर रहा था, और VSCode ने सब कुछ के बाद इंडेंट किया export class... {, जिसे कोणीय पसंद नहीं आया, जिससे मुझे यह मुद्दा मिला। प्रारूपण को ठीक करने के बाद, बिना किसी समस्या के संकलित किया गया।
गाइ पार्क

0

टिम के जवाब के अलावा, यह मुद्दा मेरे लिए तब हुआ जब मैं एक फाइल को रिफलेक्ट कर रहा था, इसे अपनी फाइलों में विभाजित कर रहा था।

VSCode, किसी कारण के लिए, मेरे [वर्ग] कोड के कुछ हिस्सों को प्रेरित करता है, जिससे यह समस्या होती है। यह पहली बार में नोटिस करना मुश्किल था, लेकिन जब मुझे पता चला कि कोड इंडेंट हो गया है, तो मैंने कोड को फॉर्मेट कर दिया और यह मुद्दा गायब हो गया।

उदाहरण के लिए, वर्ग परिभाषा की पहली पंक्ति के बाद सब कुछ पेस्ट के दौरान ऑटो-इंडेंट किया गया था।

export class MyClass extends Something<string> {
    public blah: string = null;

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