Je travaille sur une usine ; j'ai besoin d'ajouter éventuellement des méthodes personnalisées. cette réponse y cette réponse nous avons réussi à le faire fonctionner presque comme prévu.
Presque parce qu'il ne fonctionne qu'avec les méthodes sans tout argument requis ; si nous essayons d'ajouter une méthode avec au moins un argument requis, nous obtenons une erreur de compilation.
J'ai essayé d'ajouter un tableau d'arguments de repos à la fois à la déclaration de l'option method
argument et M
(voir ci-dessous) mais cela n'aide que lors de l'appel des méthodes.
(this: E & S, ...args: unknonwn[]) => unknown
type Base = { id: string }
type Factory<E> = new () => E;
function factory<E extends Base>(name: string): Factory<E>;
function factory<E extends Base, M extends Record<string, <S extends M>(this: E & S, ...args: unknown[]) => unknown>>(
name: string, methods: M & Record<string, ((this: E & M, ...args: unknown[]) => void)>
): Factory<E & M>;
function factory<E extends Base, M extends Record<string, <S extends M>(this: E & S) => unknown>>(
name: string, methods?: M
): Factory<E> {
const ret = function (this: Base) {
this.id = "0"
};
Object.defineProperty(ret, "name", { value: name });
if (methods) for (const method in methods) Object.defineProperty(ret.prototype, method, { value: methods[method] });
return ret as unknown as Factory<E>;
}
const T1 = factory("T1");
const t1 = new T1();
console.log(t1, t1.id);
const T2 = factory(
"T2",
{
foo: function (repeat: boolean) {
const ret = ! repeat;
if(repeat) this.foo(ret);
return ret;
}
},
);
const t2 = new T2();
console.log(t2, t2.id, t2.foo(true));
Voici un terrain de jeux pour faire des expériences.