How to import js from Typescript

2 분 소요

Typescript에서 외부 js 파일을 가져오는 방법을 몇 가지 알아보겠습니다.
5년전 만해도 매우 생소했던 Typescript가 Angular를 필두로 최근 몇 년 사이에 활용 빈도가 급격히 증가하여 React나 Vue.js를 비롯하여 심지어 node.js도 사용할 정도로 대세가 되었습니다.

하지만 딱 한가지 문제가 있다면 바로 기존 js 파일을 그대로 쓸 수 없다는 점입니다.
js를 Typescript가 이해할 수 있도록 d.ts라는 일종의 정의 파일을 만들면 된다고 하는데
직접 만드는 방법을 간단한 예제로 알아보고, 자동으로 쉽게 d.ts 파일을 만들 수 있는 방법도 함께 알아보도록 하겠습니다.

npm에서 install 하는 경우 옵션으로 처리

npm install @types/[filename]

npm으로 외부 라이브러리를 가져올 때는 쉽게 @types를 붙이면 node_modules/@types에 d.ts 파일이 생성됩니다.

예를 들어 qrcode.js를 npm으로 가져온다고 했을 때, qrcode와 함께 @types/qrcode를 install 합니다.

npm install qrcode  @types/qrcode

node_modules/@types/qrcode가 생성되어 있고 index.d.ts를 열어보면 Typescript에서 사용할 수 있는 코드가 자동으로 생성되어 있음을 확인할 수 있습니다.

// Type definitions for qrcode 1.3
// Project: http://github.com/soldair/node-qrcode
// Definitions by: York Yao <https://github.com/plantain-00>
//                 Michael Nahkies <https://github.com/mnahkies>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped

/// <reference types="node" />

import * as stream from "stream";

export type QRCodeErrorCorrectionLevel = "low" | "medium" | "quartile" | "high" | "L" | "M" | "Q" | "H";

export interface QRCodeOptions {
    /**
     * QR Code version. If not specified the more suitable value will be calculated.
     */
    version?: number;
    /**
     * Error correction level.
     * Possible values are low, medium, quartile, high or L, M, Q, H.
     * Default: M
     */
    errorCorrectionLevel?: QRCodeErrorCorrectionLevel;
    /**
     * Helper function used internally to convert a kanji to its Shift JIS value.
     * Provide this function if you need support for Kanji mode.
     */
    toSJISFunc?: (codePoint: string) => number;
}

export interface QRCodeToDataURLOptions extends QRCodeRenderersOptions {
    /**
     * Data URI format.
     * Default: image/png
     */
    type?: "image/png" | "image/jpeg" | "image/webp";
    rendererOpts?: {
        /**
         * A Number between 0 and 1 indicating image quality if the requested type is image/jpeg or image/webp.
         * Default: 0.92
         */
        quality?: number;
    };
}
//... (생략)

생성된 d.ts 파일을 Typescript 에서 import 할 때 import as 를 사용할 수 있습니다.

import * as qqq from 'qrcode';
...
ngOnInit(){
 let qrcodeTest: qqq.QRCode = qqq.create('Qrcode Create Test', <qqq.QRCodeOptions>{
   errorCorrectionLevel: 'H'
 });
}

기존 import 방식처럼 사용할 수도 있습니다. 그러나 이 경우 export 된 함수명이 기존 함수명과 겹칠 수 있으니 유의하여야 합니다.

import {create, QRCode, QRCodeOptions} from 'qrcode';
...
  ngOnInit() {
    const qrcodeTest: QrCode = create('ttt', <QRCodeOptions> {
      errorCorrectionLevel: 'H'
    });
  }

npm에서 install 하지 않는 경우

이 때는 직접 만들어야 하는데 방식은 간단합니다.

  • 해당 js파일에 module.export를 추가합니다.
  • d.ts 파일을 만듭니다.
  • Typescript에서 호출합니다.

다음의 test.js 파일이 있다고 가정해봅시다.

function test1(){
    return test2('test1');
}

function test2(str){
    return 'test2' + str;
}

위의 파일에 module.export를 추가해 줍니다.
이 때, export하고자 하는 값만 골라 안에 Object 형태로 넣습니다.

export할 key는 자유롭게 입력할 수 있으나 내장 함수명이나 가능하면 다른 함수들과 이름이 겹치지 않도록 해야 합니다.
겹치더라도 import as 로 사용할 수 있으니 크게 걱정할 부분은 아니지만 실수로 오류를 일으킬 수 있는 부분을 가급적 피하는 것이 좋습니다.
만일 함수에 파라미터가 있다면 정확히 넣어주어야 합니다.

module.exports = {
    testfunction: function(){return test1();},
    aaa: function(str){return test2(str);}
};

function test1(){
    return test2('test1');

}

function test2(str){
    return 'test2' + str;
}

이제 js 파일은 외부로 나갈 준비가 되었습니다. 이제 .d.ts 파일을 생성해 보겠습니다. 파일명은 js와 동일하지 않아도 됩니다.
d.ts 파일의 핵심은 js 파일을 import하고 js파일에 만들어 둔 module.export의 key를 declare function의 함수명으로 나열하는 것입니다.
어찌보면 중복 작업이지만 작성하지 않으면 Typescript에서 인식하지 않으므로 열심히 작성 합시다.

import './test.js';

declare function testfunction(): string;
declare function aaa(str): string;

이제 다 끝났습니다.
Typescript에서 import 해봅시다.
import 할 때는 d.ts 경로를 입력하면 됩니다.

import * as temp from './test';

ngOnInit(){
  console.log(temp.testfunction(), temp.aaa('this.is test'));
}

댓글남기기