I'm developing wrapper class, which can call inner instance's method with string argument.
The whole code is like below.
class Inner {
public prop1: string = 'publicProp';
private prop2: string = 'privateProp';
method1(param1: string) {
console.log(`${param1}`);
}
method2(param1: number, param2: number) {
console.log(`${param1}, ${param2}`);
}
}
This class is original class have core functions.
type Fn = (...args: any) => any;
This is type needed in below
class Outer {
private inner = new Inner();
// I want proxy's second parameter's type will be changed according to first parameter's value
public proxy<
// F type is callable member's key
F extends keyof {
[K in keyof Inner as Inner[K] extends Fn ? K : never]: any;
},
// P type will be changed according to first argument type.
P extends Parameters<Inner[F]>,
>(name: F, ...args: P) {
const fn = this.inner[name];
if (typeof fn === 'function') {
// This is right pain point!!
// TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
fn(...args);
}
}
}
The part of fn(...args) keeps showing error like above. I think, args should be inferred as tuple because we let the compiler know args's type will be extended by Parameter<Inner[F]>. How can I fix it?
const outer = new Outer().proxy;
// IDE can infer parameter's type from second parameter
outer('method1', 'stringArg');
outer('method2', 1, 2);
Another pain point is that the IDE can infer the parameter types according to first argument. (The real snapshot of IDE is attached below)
Thanks in advance your answer! :)