I'm in the process of developing a vanilla JavaScript library and have a JS class that looks like this:
class MyClass {
static create() {
return new MyClass();
}
doOneThing() {
// ...
return this;
}
doOtherThing() {
// ...
return this;
}
}
module.exports = MyClass;
This allows for a DSL-like syntax to be used:
MyClass
.create()
.doOneThing()
.doOtherThing();
I am now trying to add a d.ts
typings file for TypeScript developers who may want to use it. This is what I have so far:
export interface MyClassInstance {
doOneThing(): MyClassInstance;
doOtherThing(): MyClassInstance;
}
export interface MyClassStatic {
create(): MyClassInstance;
}
declare const MyClass: MyClassStatic;
export default MyClass;
With TypeScript, the import statement would look like this:
import MyClass from "./src/MyClass";
However, when working in a JavaScript file, my IDE suggests using:
MyClass.default.create();
I have considered wrapping my class in an object for consistent behavior between TS and JS but prefer not to go with that approach.
So my question is, is there another way to achieve both static method and default export working seamlessly in both JS and TS?
UPDATE 1
I have discovered that I can declare a class instead of an interface in my .d.ts
file like this:
declare class MyClass {
static create(): MyClass;
doOneThing(): this;
doOtherThing(): this;
}
export default MyClass;
Both JS and TS seem to work well with this approach, although I am still evaluating if it's best practice.
UPDATE 2
It appears that this is the most suitable solution. I also reviewed the DefinitelyTyped repo and noticed that some modules use the class
declaration in their typings, so I believe this approach is acceptable.