How to import js from Typescript

3 분 소요

Let’s explore several methods for importing external JavaScript files within TypeScript. A few years ago, TypeScript was relatively unknown. However, spearheaded by Angular, its adoption has surged in recent years, becoming a mainstream choice for React, Vue.js, and even Node.js projects.

However, a key challenge arises: existing JavaScript files cannot be directly used. To enable TypeScript to understand JavaScript code, a definition file, known as d.ts, is necessary. We’ll walk through creating these definition files with a simple example and explore methods to automate their generation.

Handling npm Package Imports

When importing external libraries through npm, utilizing @types provides a straightforward solution. Adding this prefix during installation generates a d.ts file within the node_modules/@types directory.

npm install @types/[filename]

For instance, when importing qrcode.js via npm, install both qrcode and @types/qrcode.

npm install qrcode @types/qrcode

This process creates node_modules/@types/qrcode. Examining the index.d.ts file reveals the automatically generated TypeScript-compatible code.

// 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;
    };
}
//... (Omitted)

When importing the generated d.ts file into TypeScript, you can use import as.

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

Alternatively, you can use the traditional import method. However, be mindful that this approach can lead to naming conflicts if the exported function name clashes with existing function names.

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

Handling Non-npm JavaScript Files

In scenarios where npm installation isn’t employed, manual creation of definition files becomes necessary. The procedure is as follows:

  • Add module.exports to the JavaScript file.
  • Create a d.ts file.
  • Call it from TypeScript.

Consider the following test.js file:

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

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

Add module.exports to this file. Ensure you include only the values you intend to export, structured as an Object. While the export keys can be named freely, avoid conflicts with built-in function names or other functions. Although potential conflicts can be resolved using import as, preventing them minimizes the risk of errors. If a function accepts parameters, ensure they are accurately defined.

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

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

}

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

The JavaScript file is now prepared for external use. Let’s create the .d.ts file. The filename doesn’t have to match the JavaScript file’s name. The core of the d.ts file involves importing the JavaScript file and declaring the function names (from the module.exports keys) using declare function. While somewhat redundant, this step is vital for TypeScript to recognize the functions.

import './test.js';

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

That concludes the setup! Let’s import this into TypeScript. When importing, specify the path to the d.ts file.

import * as temp from './test';

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

댓글남기기