d512
d512

Reputation: 34093

How to use declaration files in TypeScript

There is something I am not getting in TypeScript when it comes to declaration files and 3rd party libraries written in pure Javascript. Let's say I have the following Javascript class:

$ cat SomeClass.js

var SomeClass = (function () {
    function SomeClass() {
    }
    SomeClass.prototype.method1 = function () {
            return "some string";
    };
    return SomeClass;
})();
exports.SomeClass = SomeClass;

And I want to get type checking for it, so I create declaration file like this:

$ cat test.d.ts

class SomeClass {
    public method1(): string;
}

Then I want to use the class and declaration file in some code:

$ cat main.ts

///<reference path="./test.d.ts"/>
import ns = module("./SomeClass");

function test(): string {
   var sc = new ns.SomeClass();
   return sc.method1();
}

When I try to compile it, I get this:

$ tsc main.ts
main.ts(2,19): The name '"./SomeClass"' does not exist in the current scope
main.ts(2,19): A module cannot be aliased to a non-module type
main.ts(5,16): Expected var, class, interface, or module

From what I can tell, the import statement requires an actual TypeScript class to exist and the reference statement isn't enough to help the compiler figure out how to handle it.

I tried changing it to

import ns = module("./test.d");

But no dice either.

The only way I can get this to actually compile and run is to use the require statement instead of import, like this:

$ cat main.ts

///<reference path="./node.d.ts"/>
///<reference path="./test.d.ts"/>
var ns = require("./SomeClass");

function test(): string {
   var sc = new ns.SomeClass();
   return sc.method1();
}

The problem with this code is that TypeScript is not running any type checking. In fact, I can totally remove the line

///<reference path="./test.d.ts"/>

and it doesn't change anything.

However, if I remove the require statement, I can get type checking, but the code blows up at runtime because there is no require statement.

$ cat main.ts

///<reference path="./test.d.ts"/>

function test(): string {
   var sc = new SomeClass();
   return sc.method1();
}

test();

$ node main.js

main.js:2
    var sc = new SomeClass();
                 ^
ReferenceError: SomeClass is not defined
    ...

Upvotes: 9

Views: 11873

Answers (1)

Markus Jarderot
Markus Jarderot

Reputation: 89171

cat test.d.ts

declare module "SomeClass.js" {
    class SomeClass {
        method1(): string;
    }
}

cat Main.ts

///<reference path="test.d.ts"/>
import ns = module("SomeClass.js");

function test() {
   var sc = new ns.SomeClass();
   return sc.method1();
}

tsc Main.ts --declarations

cat Main.js

var ns = require("SomeClass.js")
function test() {
    var sc = new ns.SomeClass();
    return sc.method1();
}

cat Main.d.ts

import ns = module ("SomeClass.js");
function test(): string;

Upvotes: 10

Related Questions