Rob Lauer
Rob Lauer

Reputation: 3171

Using RequireJS with TypeScript and Retaining Intellisense

I've gotten used to using TypeScript in Visual Studio, but only to write plain JavaScript (I realize the power of TypeScript's custom syntax, but prefer to hedge my bets and maintain my JS proficiency!). My question has to do with utilizing RequireJS in this environment. For example:

require(["jquery", "app/utils.js"], function ($, utils) {
    console.log(utils.doSomething());
});

...and my utils.js looks like this:

define([], function () {
    var doSomething = function () {
        return "ok";
    };
    return {
        doSomething: doSomething
    };
});

This is what I write in TypeScript. In my perfect little world, I would love to be able to utilize intellisense to see the properties of utils in this case (so when I'm typing utils, I see utils.doSomething as an option).

I'm guessing the answer is "can't do it" and I have to use the import/export TS syntax, but thought I would check anyway!

Upvotes: 2

Views: 1436

Answers (3)

Stephen Chung
Stephen Chung

Reputation: 14605

TypeScript defaults to CommonJS-style of module exports (i.e. assigning members to the exports variable). This is the way to do it in TypeScript with Intellisense support for Visual Studio:

define([], function () {
    var doSomething = function () {
        return "ok";
    };
    var r = {
        doSomething: doSomething
    };
    export = r;
});

However, if you want to stay 100% in JavaScript, you'll need to write a type definition file app.d.ts for your module to provide the type information:

declare module "app/utils"
{
        function doSomething(): string;
}

In your app:

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

require(["jquery", "app/utils"], function ($, utils) {
    console.log(utils.doSomething());
});

Upvotes: 4

basarat
basarat

Reputation: 275997

You can define the interface inline :

require(["jquery", "app/utils.js"], function ($, utils : { doSomething:()=>string; } ) {
    console.log(utils.doSomething());
});

Or outside

interface IUtils {
    doSomething:()=>string; 
}
require(["jquery", "app/utils.js"], function ($, utils : IUtils ) {
    console.log(utils.doSomething());
});

Upvotes: 0

Damian
Damian

Reputation: 2789

If utils.js is indeed a javascript file then TypeScript isn't going to give you intellisense for free. You need to write declarations for javascript files:

So you can create a utils.d.ts file which looks like this:

module utils {
    doSomething():string;
}

This will enable you to add this to your original file:

///<reference src="app/utils.d.ts" />

And now you should get intellisense.

This however feels very wrong, as why would you write definition files for new javascript code you are writing yourself, this is almost like writing the code twice. If you can just bite the bullet and go with typescript, you should. Hedging your bets in going to give you more work (of course if we are talking existing code then the definition/declaration files are probably worth it as you won't have to port existing code.

Upvotes: 1

Related Questions