Reputation: 247
PLEASE SEE MORE DETAILED QUESTION: How do I write a TypeScript declaration file for a complex external commonjs module that has constructor, such as imap?
I write TypeScript for a Node.js app, and I want to write a TypeScript declaration file for a javascript module (available from npm) that has a constructor at the module level.
Here is a simplified version of the relevant code, in file a.js:
function A(config) {
this.state = 'constructed';
}
A.prototype.update = function() {
this.state = 'updated';
};
module.exports = A;
and a simplified javascript application, app.js, that uses module a:
var mod = require('a');
var i = new mod({});
console.log('i.state=' + i.state);
i.update();
console.log('i.state=' + i.state);
How do I write a TypeScript declaration file for module a.js?
I've read the TypeScript Guide for Writing Definition (.d.ts) Files but unfortunately, I couldn't figure out how to apply the guidelines to this case.
Here is my declaration file a.d.ts:
declare module 'a' {
import events = require('events');
import EventEmitter = events.EventEmitter;
interface Config {
foo: number;
}
interface Other {
baz: number;
}
class A extends EventEmitter {
state: string;
constructor(config: Config);
update(): void;
}
var out: typeof A;
export = out;
}
I can't figure out how to make the interfaces available to my TypeScript app. I also want to keep them within the module, so that names like Config don't collide with those from other modules.
This is what I expect my app.ts to look like:
import mod = require('a');
import Config = mod.Config;
import Other = mod.Other;
var other : Other = {a: 2};
var config : Config = {foo: 2};
var i = new mod(config);
console.log('i.state=' + i.state)
i.update();
console.log('i.state=' + i.state)
Upvotes: 5
Views: 5107
Reputation: 247
I found an existing declaration file for a modules that has similar structure to the one for which I want to write a declaration file: auth0
I now have something that works, although not yet ideal. The declaration file a.d.ts is:
/// <reference path='node.d.ts' />
interface Config {
foo: number;
}
declare module 'a' {
import events = require('events');
import EventEmitter = events.EventEmitter;
class A extends EventEmitter {
constructor(config : Config);
state: string;
update(): void;
}
var out: typeof A;
export = out;
}
with the TypeScript app file app.ts being:
/// <reference path='a.d.ts' />
import mod = require('a');
var config : Config = {
foo: 1
}
var i = new mod(config);
console.log('i.state=' + i.state)
i.update();
console.log('i.state=' + i.state)
and the a.js module being as in the original question.
I compile this with: tsc --module commonjs app.ts
This certainly works for now.
Although I think it's messy to have the interface (Config) outside of the module, but I haven't yet figured out how to move the interfaces inside.
Upvotes: 1
Reputation: 4463
There are a couple ways to do this, here is one:
declare class A {
state: string;
constructor(config: any);
update(): void;
}
declare module 'a' {
var out: typeof A;
export = out;
}
EDIT: If you want to include interfaces, but also have an exported class, you can set it up like this:
declare module A {
class A {
state: string;
constructor();
update(): void;
}
interface B {
value: any;
}
}
declare module 'a' {
var out: typeof A.A;
export = out;
}
Upvotes: 3