"… 모듈이 아닌 엔티티로 해석되고이 구성을 사용하여 가져올 수 없음"은 무엇을 의미합니까?


93

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

이것은 사용하려고 할 때 오류가 발생합니다. new

"MyClass"모듈은 비 모듈 엔티티로 해석되며이 구성을 사용하여 가져올 수 없습니다.

그리고 전화하려고 할 때 fn()

형식에 호출 서명이없는 식을 호출 할 수 없습니다.

무엇을 제공합니까?


2
답변을 공유해 주셔서 감사합니다. 여기에 기본 태그가 있기 때문에 javascript기본 태그 로 제거 하고 떠나는 것이 좋습니다 . 문제는 잘못했다고 가정 의 (a TS 기능)와 결합 할 수 있지만, 이와 결합되어야한다 . 기본적으로 ES6 모듈 가져 오기 / 내보내기 대 CJS / AMD입니다. ecmascript-6typescriptexport =import ... fromimport =
Estus Flask 16.09.09

답변:


156

작동하지 않는 이유

import * as MC from './MyClass';

이것은 ES6 / ES2015 스타일 import구문입니다. 이것의 정확한 의미는 " 로드 된 모듈 네임 스페이스 객체를 가져 ./MyClass와서 로컬로 사용 MC"입니다. 특히, "모듈 네임 스페이스 객체 "는 속성이있는 일반 객체로만 구성됩니다. ES6 모듈 객체는 함수로 또는 new.

다시 말하면 : ES6 모듈 네임 스페이스 객체는 함수로 또는 new.

모듈에서 import사용 하는 것은 * as X속성 만 갖도록 정의됩니다. 하위 CommonJS에서 이것은 완전히 존중되지 않을 수 있지만 TypeScript는 표준에 의해 정의 된 동작이 무엇인지 알려줍니다.

작동하는 것은 무엇입니까?

이 모듈을 사용하려면 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 모델 : Acceptance의 5 단계로 이동하십시오.

TypeScript는 이것이 작동하지 않기 때문에 작동하지 않는다고 말합니다. 해킹이 있습니다 ( namespace선언을 추가하는 것이이 MyClass작업을 가장하는 인기있는 방법입니다). 오늘은 특정 하향 레벨링 모듈 번 들러 (예 : 롤업)에서 작동 할 있지만 이것은 환상적입니다. 아직 ES6 모듈 구현은 없지만 영원히 사실은 아닙니다.

neato 네이티브 ES6 모듈 구현에서 실행 하려고 시도하고 ES6 구문을 사용하여 ES6가 명시 적으로 수행하지 않는 작업시도 함으로써 중대한 실패에 대비 한 자신을 발견하는 미래의 모습을 상상해보십시오 .

비표준 모듈 로더를 활용하고 싶습니다.

아마도 default존재하지 않을 때 "유용하게" 내보내기를 생성하는 모듈 로더가 있을 수 있습니다. 사람들은 이유가있어 표준을 만들지 만 표준을 무시하는 것은 때때로 재미 있고 우리는 그것이 멋진 일이라고 생각할 수 있습니다.

MyConsumer.ts 를 다음으로 변경 하십시오 .

import A from './a';

그리고 allowSyntheticDefaultImports명령 줄 또는 tsconfig.json옵션을 지정합니다 .

참고 allowSyntheticDefaultImports전혀 코드의 런타임 동작을 변경하지 않습니다. 모듈 로더가 default존재하지 않을 때 내보내기를 생성한다는 것을 TypeScript에 알려주는 플래그 일뿐입니다 . 이전에하지 않았던 nodejs에서 코드가 마술처럼 작동하도록 만들지는 않습니다.


commonjs 스타일에는 commonjs 대상이 필요하지 않습니까? es6 / es2015를 대상으로 할 때이 작업을 수행 할 수있는 방법이 있습니까?
Steve Buzonas 2017-06-13

당신은 ES6을 대상으로 작업 할 수 없습니다 가 ES6에서 작동하지 않기 때문에 ...
라이언 카바

ES2015 모듈을 대상으로하는 경우 다음과 같은 CommonJS 모듈을 참조 할 방법이 없다는 것을 이해하는 것이 맞 export = MyClass습니까? 내 유일한 옵션은 내 모듈을로 설정하고 commonjs최신 ES를 사용하지 않음으로써 세상을 계속해서 더 나쁜 곳으로 만드는 것입니까?
Micah Zoltu

6
에서 2.7 릴리스 노트 , 아래 --esModuleInterop, 그것은 "우리는 매우 신규 및 기존 프로젝트에 모두 적용하는 것이 좋습니다"라고. 제 생각에는,이 답변 (그리고 질문 항목 / 정책DefinitelyTyped여기에 링크) 새로운 입장을 반영하기 위해 수정해야합니다.
Alec Mev

1
너무나 엉뚱 해요.
jmealy dec.

25

TypeScript 2.7은 새로운 도우미 메서드를 생성하여 지원을 소개합니다 : https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-form- commonjs-modules-with --- 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그리고 그것은 나를 위해 일했습니다.
Edgar Quintero

6

다른 사람이이 문제를 가지고있을 경우를 대비하여 여기에 2 센트를 추가합니다.

수정하지 않고 문제를 해결하는 방법 tsconfig.json(일부 프로젝트에서는 문제가 될 수 있음)으로 간단히 한 줄에 대한 규칙을 비활성화했습니다.

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


5

내 프로젝트에 npm 디 바운스 패키지를 포함하려고 할 때이 오류가 발생했습니다.

위의 허용 된 솔루션을 시도했을 때 예외가 발생했습니다.

ECMAScript 모듈을 대상으로 할 때는 가져 오기 할당을 사용할 수 없습니다. 대신 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"'또는 다른 모듈 형식을 대신 사용해보십시오.

이것은 결국 작동했습니다.

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