program story

Typescript es6 가져 오기 모듈 "파일이 모듈 오류가 아닙니다."

inputbox 2020. 8. 27. 07:45
반응형

Typescript es6 가져 오기 모듈 "파일이 모듈 오류가 아닙니다."


es6 모듈 구문과 함께 typescript 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'파일이 모듈이 아닙니다.

어떻게 할 수 있습니까?


확장 -일부 의견에 따라 더 자세한 정보를 제공합니다.

오류

오류 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())

원래 부분은 네임 스페이스 사용의 복잡성을 줄이기 위해 노력하고 있습니다.

원래 부분 :

이 Q & A를 확인하는 것이 좋습니다.

TypeScript 외부 모듈에서 네임 스페이스를 어떻게 사용합니까?

첫 번째 문장을 인용하겠습니다.

외부 모듈에서 "네임 스페이스"를 사용하지 마십시오.

이러지마

진지하게. 중지.

...

In this case, we just do not need module inside of test.ts. This could be the content of it adjusted test.ts:

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

Read more here

Export =

In the previous example, when we consumed each validator, each module only exported one value. In cases like this, it's cumbersome to work with these symbols through their qualified name when a single identifier would do just as well.

The export = syntax specifies a single object that is exported from the module. This can be a class, interface, module, function, or enum. When imported, the exported symbol is consumed directly and is not qualified by any name.

we can later consume it like this:

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

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

sc.getName();

Read more here:

Optional Module Loading and Other Advanced Loading Scenarios

In some cases, you may want to only load a module under some conditions. In TypeScript, we can use the pattern shown below to implement this and other advanced loading scenarios to directly invoke the module loaders without losing type safety.

The compiler detects whether each module is used in the emitted JavaScript. For modules that are only used as part of the type system, no require calls are emitted. This culling of unused references is a good performance optimization, and also allows for optional loading of those modules.

The core idea of the pattern is that the import id = require('...') statement gives us access to the types exposed by the external module. The module loader is invoked (through require) dynamically, as shown in the if blocks below. This leverages the reference-culling optimization so that the module is only loaded when needed. For this pattern to work, it's important that the symbol defined via import is only used in type positions (i.e. never in a position that would be emitted into the JavaScript).


How can I accomplish that?

Your example declares a TypeScript < 1.5 internal module, which is now called a namespace. The old module App {} syntax is now equivalent to namespace App {}. As a result, the following works:

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

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

That being said...

Try to avoid exporting namespaces and instead export modules (which were previously called external modules). If needs be you can use a namespace on import with the namespace import pattern like this:

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

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

Above answers are correct. But just in case... Got same error in VS Code. Had to re-save/recompile file that was throwing error.


In addition to A. Tim's answer there are times when even that doesn't work, so you need to:

  1. Rewrite the import string, using the intellisense. Sometimes this fixes the issue
  2. Restart VS Code

In addition to Tim's answer, this issue occurred for me when I was splitting up a refactoring a file, splitting it up into their own files.

VSCode, for some reason, indented parts of my [class] code, which caused this issue. This was hard to notice at first, but after I realised the code was indented, I formatted the code and the issue disappeared.

for example, everything after the first line of the Class definition was auto-indented during the paste.

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

    constructor() { ... }
  }

참고URL : https://stackoverflow.com/questions/32805559/typescript-es6-import-module-file-is-not-a-module-error

반응형