I want to get a type that maps method names to their return values. The first step is to extract keys that represent methods of that class.
I tried this:
type ClassMethods<TClass> = {
[K in keyof TClass] : TClass[k] extends (...args: any[])=>any ? "func" : never;
}
I asked an LLM and it gave me basically the same exact code. However, when I try it, the ClassMethods
object contains all keys from the class, not just methods:
class TestClass {
constructor(public test: string) {
this.test = test;
}
public testMethod() {
return this.test;
}
public async testMethodAsync() {
return this.test;
}
}
const testClassMethods = null as ClassMethods<TestClass>;
testClassMethods.[CTRL SPACE HERE]
.test
.testMethod
.testMethodAsync
Screenshot from VS Code:
The reason I am doing this is that ultimately I want to generate a type that maps all sync methods to async
but keeps async
and async *
methods as-is. This is to generate a type that represents remote side of an RPC client. Additionally I will be doing an intersection with a type that has list of methods that are allowed to be called by an RPC.
But in this question, I just want the above to work - the testClassMethods
type should evaluate to:
{
testMethod: "func",
testMethodAsync: "func"
}
You need to use key remapping with as
:
type ClassMethods<TClass> = {
[K in keyof TClass as TClass[K] extends (...args: any[]) => any ? K : never]: "func";
};
In the code above as TClass[K] extends (...args: any[]) => any ? K : never
filters out non-method keys.
I checked this version in VSCode and the autocomplete works correctly now.