Typescript es6 import module“파일이 모듈 오류가 아닙니다”


127

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'파일이 모듈이 아닙니다.

어떻게하면 되나요?


나는이 문제가 있었고, 클래스에 생성자가 없었고, 하나를 추가하고 문제가 사라졌습니다
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())

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

원래 부분 :

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

TypeScript 외부 모듈과 함께 네임 스페이스를 사용하려면 어떻게합니까?

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

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

이러지 마

진심으로. 중지.

...

이 경우에는 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();

더 많은 것을 읽으십시오 :

선택적 모듈 로딩 및 기타 고급 로딩 시나리오

경우에 따라 특정 조건에서만 모듈을로드 할 수 있습니다. TypeScript에서는 아래 표시된 패턴을 사용하여 유형 및 기타 고급 로딩 시나리오를 구현하여 유형 안전성을 잃지 않고 모듈 로더를 직접 호출 할 수 있습니다.

컴파일러는 각 모듈이 방출 된 JavaScript에서 사용되는지 여부를 감지합니다. 유형 시스템의 일부로 만 사용되는 모듈의 경우 필요 호출이 발생하지 않습니다. 이러한 미사용 참조 컬링은 성능을 최적화하는 데 도움이되며 해당 모듈을 선택적으로로드 할 수도 있습니다.

이 패턴의 핵심 아이디어는 import id = require ( '...') 문을 통해 외부 모듈에 의해 노출 된 유형에 액세스 할 수 있다는 것입니다. 아래 if 블록에 표시된대로 모듈 로더는 동적으로 (요구 사항을 통해) 호출됩니다. 이는 참조 컬링 최적화를 활용하여 필요할 때만 모듈이로드되도록합니다. 이 패턴이 작동하려면 가져 오기를 통해 정의 된 기호가 형식 위치에서만 사용되는 것이 중요합니다 (즉, JavaScript로 방출되는 위치에서는 사용되지 않아야 함).


1
그러나 이것은 : import App = require ( './ test'); es6 모듈의 구문이 아닙니다. 이것은 일반적인 js입니다. es6 모듈 구문으로 할 수 있습니까?
Bazinga

@JsIsAwesome JS 모듈을 Typescript 모듈과 혼합하려고합니다. 둘을 혼합하지 않고 둘 중 하나를 사용해야합니다.
JJJ

이 답변은 ES6 구문을 참조하지 않습니다
phiresky

@phiresky, 무슨 뜻인가요?
Radim Köhler

1
고마워요
phiresky

24

위의 답변이 맞습니다. 그러나 경우에 대비하여 ... VS 코드에서 동일한 오류가 발생했습니다. 오류가 발생한 파일을 다시 저장 / 재 컴파일해야했습니다.


3
이것은 나를 위해 일했습니다. 세미콜론을 제거하고 다시 추가하고 파일을 다시 저장 한 다음 Webpack을 실행하면됩니다. 살기 좋은 시간.
Ray Hogan

1
나는 Webstorm에 익숙하고 파일이 VS 코드로 자동 저장되지 않는다는 것을 알지 못했습니다. 이 답변은 많은 고통을 덜어주었습니다. 감사합니다.
cib

VS 코드에 자동 저장 설정이 있습니다. VS 코드는 저장되지 않은 파일을 이미 백업하고 항상 git을 사용하지 않기 때문에 사용하지 않습니다.
aamarks

13

어떻게하면 되나요?

이 예제에서는 TypeScript <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 사양에 따라 불법입니다".
Andrey Prokhorov

2

A. Tim의 답변 외에도 작동하지 않는 경우가 있으므로 다음을 수행해야합니다.

  1. 인텔리전스를 사용하여 가져 오기 문자열을 다시 작성하십시오. 때때로 이것은 문제를 해결합니다
  2. VS 코드 재시작

1
stackblitz에 대한 동일 - 재 컴파일 파일이 수입 모듈 및 모든 작품 벌금, 환호
godblessstrawberry

내 코드가 올바르게 포맷되지 않은 경우 에도이 문제가 발생했습니다. VSCode는 클래스를 자체 파일로 분할 할 때 복사 + 붙여 넣기 클래스 코드를 들여 쓰기했으며 VSCode export class... {는 각도가 마음에 들지 않는. 서식을 수정 한 후 문제없이 컴파일되었습니다.
Guy Park

0

Tim의 답변 외에도이 문제는 파일 리팩토링을 분할하고 자체 파일로 분할 할 때 나에게 발생했습니다.

VSCode는 어떤 이유로 내 [클래스] 코드의 일부를 들여 쓰기 하여이 문제를 일으켰습니다. 처음에는 눈에 띄지 않았지만 코드가 들여 쓰기 된 것을 알면 코드를 포맷하고 문제가 사라졌습니다.

예를 들어 클래스 정의의 첫 번째 줄 이후의 모든 항목은 붙여 넣기 중에 자동 들여 쓰기됩니다.

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

    constructor() { ... }
  }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.