I am rewriting an old NPM module in TypeScript, and I ran into an interesting problem.
The module, in its current state, looks like this -
1.1 my-module.js
export function init(options) {
//initialize module
}
export function doStuff(params) {
//do stuff with options and other things
}
1.2 example.js
var m = require('my-module');
m.init({thing: 'doodad'});
m.doStuff('bwoah');
I'm rewriting this in TS (targeting ES6), and plan to write the module as a class that can take a constructor (in lieu of init()
), letting me write nice things like -
1.3 example-new.js
import {Thing} from 'my-module';
const aThing1 = new Thing({thing: 'doodad'});
const aThing2 = new Thing();
aThing2.init({thing: 'doodad'});
aThing1.doStuff('bwoah');
aThing2.doStuff('bwoah');
// If I can do at least one of aThing1 or aThing2, I can die a happy man.
The rewritten TypeScript module looks like this -
1.4 my-module-new.js
class Thing {
options: Object;
constructor(options: Object) {
this.options = options;
}
init(options: Object) {
this.options = options;
return this;
}
doStuff(thingForStuff: string) {
// ...
}
}
What I'd like to achieve
I want to maintain full backwards-compatibility with the old API as well. So ideally, I should be able to do both 1.2 and 1.3.
What I've tried so far
export
ing theThing
class; this lets me do 1.3, but not 1.2.export
ing a singleton, withexport default new Thing()
; this lets me do 1.3, but not 1.2.Writing something like this -
export class Thing {
options: Object;
constructor(options: Object) {
this.options = options;
}
init(options: Object) {
this.options = options;
return this;
}
doStuff(thingForStuff: string) {
// ...
}
}
const singleThing = new Thing();
export function init(options) {
return singleThing.init(options);
}
export function doStuff(string) {
return singleThing.doStuff(string);
}
This works well with both 1.2 and 1.3 - but this seems tedious to basically duplicate each function.
Surely there must be a more elegant way of doing this?