Answer the question
In order to leave comments, you need to log in
What is the best way to export a class so that it can be called as a function?
Let's say we have this code
class BaseLol { /* ... */ }
class Lol extends BaseLol {
constructor(public name: string) {
super();
this.name = name.toUpperCase();
}
}
import lol from './lol';
const instance = lol('qwe');
export default (name: string) => new Lol(name);
export default (...args: ConstructorParameters<typeof Lol>) => new Lol(...args);
function exportLol(classFromExport) {
return (...args) => new classFromExport(...args);
}
export default exportLol(Lol);
class BaseLol {
constructor() {
return new Proxy(this, {
get(target, prop) {
if (prop === "init") {
return (...args: any) => {
const clone = Object.assign(
Object.create(Object.getPrototypeOf(target)),
target
);
clone.init(...args);
return clone;
};
}
},
});
}
/* ... */
}
class Lol extends BaseLol {
init(name: string) {
this.name = name.toUpperCase();
return this;
}
}
export default new Lol().init;
import lol from './lol';
const instance = lol('qwe');
Answer the question
In order to leave comments, you need to log in
Are you too lazy to write new
? IMHO, this is overkill. Your hands will not fall off to write three extra characters, and it will be much clearer than incomprehensible unnecessary functions.
But the races are so desirable, then the type for your function is as follows:
function exportConstruct<P extends any[], T>(classFromExport: { new (...args: P): T; }):
(...args: P) => T {
return (...args) => new classFromExport(...args);
}
function exportCallable<T extends { new (...args: any[]): any; }>(classFromExport: T) {
return new Proxy(classFromExport, {
apply(ctor, _, args) {
return new ctor(...args);
}
}) as T & ((...args: ConstructorParameters<T>) => InstanceType<T>);
}
const Lol = exportCallable(class Lol extends BaseLol {
constructor(public name: string) {
super();
this.name = name.toUpperCase();
}
});
Lol('qwe');
abstract class Newable {
static new<P extends any[], T>(this: { new (...args: P): T; }, ...args: P): T {
return (new this(...args)) as T
}
}
class BaseLol extends Newable { /* ... */ }
class Lol extends BaseLol {
constructor(public name: string) {
super();
this.name = name.toUpperCase();
}
}
Lol.new('qwe');
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question