Jeroen
Jeroen

Reputation: 63840

Create type definition for method exposed on namespace

I'm converting an existing JavaScript application to Typescript. I start with:

// file1.js
(function(ns) {
  ns.bar = function() { };
}(window.MyNamespace || {}));
// file2.js
(function(ns) {
  ns.Item = function() {
    this.doStuff = function() { ns.bar(); };
  }
}(window.MyNamespace || {}));

Now I'm converting file2.js to TypeScript:

module MyNamespace {
  class Item {
    doStuff() {
      MyNamespace.bar(); // This is obviously a problem
    }
  }
}

There is a problem with calling bar. I understand that converting file1.js to TypeScript will make things a lot easier, but that file is quite large in reality so I want to do the conversion next sprint and get a intermediary situation.

How do I solve that? How do I tell tsc that bar is a function on the module itself?

I've tried declare var bar: () => void; inside the module and variations thereof, but didn't get it to work so far.

I know I could consider converting those "namespace-functions" to static methods on a class, but that would require rewriting file1.js now, which I don't want (yet).

I've got a workaround like this:

module MyNamespace {
  var ns: any = MyNamespace;

  class Item {
    doStuff() {
      ns.bar();
    }
  }
}

But that feels a bit off, not in the least because it requires changes inside my class, whereas I'd prefer to have a bridge between file2.ts and file1.ts seperate from the final file2.ts stuff.

In essence, I feel like I'm writing a .d.ts file for my original file1.js functionality that will make file2.ts work now, in a way that can remain unchanged after converting file1.js to .ts.

Any tips? How do I create a typing for my unconverted file1.js?

Upvotes: 0

Views: 52

Answers (1)

Philip Bijker
Philip Bijker

Reputation: 5115

Add a declare statement next to the module like this:

declare module MyNamespace {
    var bar: () => void;
}

module MyNamespace {
  class Item {
    doStuff() {
      MyNamespace.bar(); // This will compile!
    }
  }
}

You could (should) remove this temporary declaration of the bar method once you've converted file1.js to Typescript

Upvotes: 1

Related Questions