Typescript: Question about importing js file in typescript fashion

Created on 10 Apr 2015  路  7Comments  路  Source: microsoft/TypeScript

I am trying to import an existing javascript source file(not a 3rd party module) into my typescript file using import ... = require() syntax with no success. Could you please help me point out anything I did wrong in the following isolated example?

add.js

module.exports = function (n1, n2) {
    return n1 + n2;
};

add.d.ts

declare module "add" {
    function add(n1: number, n2: number): number;
    export = add;
}

main.ts

/// <reference path='node.d.ts' />
/// <reference path='add.d.ts' />
import add = require('./add');
console.log(add(1, 2));

When I try to compile main.ts, I got the following error:

error TS2306: File 'add.d.ts' is not an external module.
Question

Most helpful comment

if you want to use relative path in the import, you will need:

  1. put the add.d.ts next to add.js
  2. define the file as an external module:
// add.d.ts
declare function add(n1: number, n2: number): number;
export = add;

i.e. loose the "declare module "add"" part.

more details:

There are two ways to define declarations for a .js module:

1 using declare module "foo" and then you can have multiple module definitions in the same file:


// mydefinitions.d.ts
declare module "mod1" {
    export var x = 0;
}

declare module "mod2" {
    export var y = 0;
}

declare module "mod3" {
    export var z = 0;
}

and consuming them would have to be using absolute names:

// main.ts

/// <reference path="myDefintions.d.ts" />
import * as mod1 from "mod1";
import mod2 = require("mod2");
import {z} from "mod3";

2 alternatively you can define as a file, where the name of the file is the name of the module

// myModule.d.ts

declare var m = 0;
export = m;

and consume it as a normal .ts module:

import m = require("./myModule");
m.toString();

All 7 comments

Since you defclared add as an ambient module, in your consumtion file, main.ts do not use relative paths.

/// <reference path='node.d.ts' />
/// <reference path='add.d.ts' />
import add = require('add');
console.log(add(1, 2));

@mhegazy This works with the compiler, but the generated js file will have var add = require(add), which is incorrect module loading code for node. Node will error at runtime:

Error: Cannot find module 'add'
    at Function.Module._resolveFilename (module.js:336:15)
    at Function.Module._load (module.js:278:25)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/Users/EricLu/Documents/Temp/main.js:3:11)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)

if you want to use relative path in the import, you will need:

  1. put the add.d.ts next to add.js
  2. define the file as an external module:
// add.d.ts
declare function add(n1: number, n2: number): number;
export = add;

i.e. loose the "declare module "add"" part.

more details:

There are two ways to define declarations for a .js module:

1 using declare module "foo" and then you can have multiple module definitions in the same file:


// mydefinitions.d.ts
declare module "mod1" {
    export var x = 0;
}

declare module "mod2" {
    export var y = 0;
}

declare module "mod3" {
    export var z = 0;
}

and consuming them would have to be using absolute names:

// main.ts

/// <reference path="myDefintions.d.ts" />
import * as mod1 from "mod1";
import mod2 = require("mod2");
import {z} from "mod3";

2 alternatively you can define as a file, where the name of the file is the name of the module

// myModule.d.ts

declare var m = 0;
export = m;

and consume it as a normal .ts module:

import m = require("./myModule");
m.toString();

Cool, this works perfectly! Thanks a lot!

How can I import a javascript file which consists of several modules with a single d.ts file by using relative paths?

Example:

// bundle.js
define('alert/alert', [
    'require',
    'exports'
], function (require, exports) {
    var Alert = function () {
        function Alert() {
        }
        Alert.prototype.alert = function (message) {
            alert(message);
        };
        return Alert;
    }();
    exports.Alert = Alert;
});
define('log/log', [
    'require',
    'exports'
], function (require, exports) {
    var Log = function () {
        function Log() {
        }
        Log.prototype.log = function (message) {
            console.log(message);
        };
        return Log;
    }();
    exports.Log = Log;
});
define('bundle', [
    'require',
    'exports',
    'alert/alert',
    'log/log'
], function (require, exports, alert_1, log_1) {
    exports.Alert = alert_1.Alert;
    exports.Log = log_1.Log;
});
// bundle.d.ts
declare module 'alert/alert' {
    export class Alert {
        alert(message: string): void;
    }

}
declare module 'log/log' {
    export class Log {
        log(message: string): void;
    }

}
declare module 'bundle' {
    import { Alert as _Alert } from 'alert/alert';
    import { Log as _Log } from 'log/log';
    export var Alert: typeof _Alert;
    export var Log: typeof _Log;

}

@canmrt add a ///

import { Log } from "log/log";

@mhegazy this works nice, thanks a lot!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MartynasZilinskas picture MartynasZilinskas  路  3Comments

jbondc picture jbondc  路  3Comments

weswigham picture weswigham  路  3Comments

bgrieder picture bgrieder  路  3Comments

Roam-Cooper picture Roam-Cooper  路  3Comments