TypeScript에서 esModuleInterop: true 이러한 프로퍼티(=속성)가 있다.
이 프로퍼티는 기본값이 false(esModuleInterop: false)로 되어있는데 false이면 TypeScript는 CommonJS, AMD, UMD 모듈도 ES6 모듈과 유사하게 처리한다. 이를 위해 다음과 같은 두 가지 방법을 활용한다.
- import * as
momentfrom "moment"는
constmoment= require("moment")로 컴파일 한다.- import
momentfrom "moment"는
constmoment= require("moment").default로 컴파일 한다.
하지만 이렇게 사용하면 각각 문제가 발생한다.
1번은 ES6 모듈 사양에는 네임스페이스 가져오기( import * as x)가 객체만 될 수 있다고 명시되어 있다.
하지만 TypeScript가 require("x") 로 컴파일 하게 한다는 것 "x" 가 호출이 가능한 함수 타입이 될 수도 있다는 뜻이다. 이는 ES6 모듈 스펙어 어긋난다.
2번은 ES6 모듈 사양에 정확하지만 CommonJS/AMD/UMD 모듈이 있는 대부분의 라이브러리는 TypeScript의 구현만큼 엄격하게 준수하지 않았습니다.
그럼 esModuleInterop: true로 지정하면
TypeScript에 의해 트랜스파일 되는 코드에서 위와 같은 두 개의 문제를 모두 해결할 수 있다.
JavaScript 코드를 만들어 낼 때 다음과 같은 두 개의 헬퍼 함수를 사용하도록 하는 것이다.
const moment = __importStar(require("moment"))const moment = __importDefault(require("moment')).default
1번은 moment가 ES6 모듈이면 module.exports 객체를 그대로 반환하고, 아니라면 module.exports의 프로퍼티들을 그대로 가지고 있으며, default 프로퍼티로는 module.exports 자체를 가리키는 또 다른 객체를 만들어 반환한다. 따라서 더 이상 import * as moment from "moment"; 에서의 moment는 호출 가능한 함수 타입이 되지 못한다.
2번은 moment가 ES6 모듈이면 module.exports 객체를 그대로 반환하고, 아니라면 default 프로퍼티로 module.exports 자체를 가리키는 또 다른 객체를 만들어 반환한다. 따라서 default export가 없는 모듈이라 하더라도 default export가 있는 모듈인 것처럼 default import로 불러와 사용할 수 있게 된다.
1번 2번 을 봤을때 또 다른 객체를 만들어 반환하는 공통점을 가지고 있다.