Reputation: 570
I'm sorry if the title is confusing, I'm not entirely sure how to phrase it better.
I'm trying to wrap my head around writing type declarations by attempting to produce one for this file (which is the source for this npm module), wherein I basically export an instance of the Eventer
class allowing the module to as a singleton but also contains a property referencing the class to create sandboxed instances. I'm using Visual Studio Code to check if the properties are correct. The module looks something like this:
// tiny-eventer.js
function Eventer () {
this.on = function (eventName, listener) { ... };
this.trigger = function (eventName, args) { ... };
}
Eventer.prototype.Eventer = Eventer;
module.exports = new Eventer();
In another module I can then use the singleton-like eventer
instance by requiring it, but also create a sandboxed instance calling new eventer.Eventer()
.
// index.js
var eventer = require('tiny-eventer');
var sandboxedEventer = new eventer.Eventer();
sandboxedEventer.on('an-event', function (args) { console.log('sandboxed ' + args); });
eventer.on('an-event', function (args) { console.log('global ' + args); });
eventer.trigger('an-event', 'is called');
// Prints to console: "global is called"
sandboxedEventer.trigger('an-event', 'is called');
// Prints to console: "sandboxed is called"
This basically means this horrific piece of code is valid too:
// sorry.js
var eventer = require('tiny-eventer');
var otherEventer = new (new (new (new eventer.Eventer()).Eventer()).Eventer()).Eventer();
As for the typings I've tried the following:
declare module 'tiny-eventer' {
...
interface TinyEventItem { listener: (args) => void }
class Eventer {
// Doesn't seem to work as it should
Eventer: Eventer;
on(eventName: String, listener: (args) => void): TinyEventItem;
trigger(eventName: string, args: any): void;
}
export = new Eventer;
}
The above will work with the singleton properts such as eventer.on
and eventer.trigger
, but also seems to allow eventer.Eventer.on
, whereby new eventer.Eventer()
isn't allowed. It feels like I'm doing this wrong.
How would I got about writing a typings file which declares a class with a property referencing itself?
Upvotes: 0
Views: 103
Reputation: 570
I figured out something that produces the result I'm looking for (in vscode's Intellisense at least), although I'm not sure it's a proper solution.
What solved it for me was the following Eventer: new Eventer;
If anyone has a better solution, please post them or update this.
declare module 'tiny-eventer' {
...
interface TinyEventItem { listener: (args) => void }
class Eventer {
on(eventName: String, listener: (args) => void): TinyEventItem;
trigger(eventName: string, args: any): void;
// This right here seems to do it
Eventer: new Eventer;
}
export = new Eventer;
}
Upvotes: 1