I would like to dynamically generate some tests, for that I have to call a method with the method name to be called and then all the test setup is done and the method is called.
So basically I call createTest('methodName')
instead of it('methodName', () => ...lotsOfBoringStuff...)
.
For that I would like to type the method appropriately, so I have autocomplete and are sure, that I only call it for the correct methods.
I managed to whip something together that "should work", but TS does complain about incompatible types:
type MethodOf<T> = {
[P in keyof T]: T[P] extends () => unknown ? P : never;
}[keyof T];
function doStuff<T, N extends MethodOf<T>>(t: T, method: N): unknown {
const meth: () => unknown = t[method]; // <-- boom: {} cannot be assigned to () => unknown
return meth();
}
const t = {
abc: 'str',
foobar: () => 1,
};
doStuff(t, 'foobar'); // <-- works as expected + autocompletion
type T1 = typeof t;
type N1 = MethodOf<T1>; // 'foobar'
type M1 = T1[N1]; // () => number // <-- works as expected
Why doesn't TS detect that T[MethodOf<T>]
is actually a callable method?
Is there an alternative to casting it to any
before assigning it?
I'm using typescript 4.6.