Let's say I have this simple class in TS.
class MyClass {
foo() {
console.log('foo');
}
bar(n: number) {
console.log(n);
}
}
const instance = new MyClass();
instance.foo(); // prints 'foo'
I would like to add an instance method delay
with this signarture:
delay(ms = 1000): Partial<MyClass>;
It should be called from the class instance, and be able to chain into other class methods, but fire them after a timeout, i.e.:
instance.foo(); // prints 'foo' immediately
instance.delay().foo(); //prints 'foo' after 1 second
instance.delay(2000).foo(); // prints 'foo' after 2 seconds
I tried constructing this method myself in what looked like a way that made sense, but I'm facing TS errors:
delay(ms = 1000): Partial<MyClass> {
const methods = [this.foo, this.bar];
return methods.reduce<Partial<MyClass>>((acc, method) => {
acc[method.name] = async (...args: Parameters<typeof method>) => {
await new Promise(resolve => { setTimeout(resolve, ms); });
return method.apply(this, args);
};
return acc;
}, {});
}
I'm pulling the methods
from the class that I would like to be available for delay, then reducing them into a partial object and creating a new method per method, the awaits a timeout internally.
But I'm getting some TS errors:
acc[method.name]
/* Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Partial<MyClass>'.
No index signature with a parameter of type 'string' was found on type 'Partial<MyClass>'. */
method.apply(this, args);
/* Source provides no match for required element at position 1 in target. /*
The second one is because different methods might have different params, and the first one is unclear to me.