I would like to make a method that receives two parameters, methodName and method, the first should only accept names of methods that exist in the class itself, and the second method should only accept functions that receive the same parameters and have the same return as the method selected by the methodName parameter, below is my failed attempt:
type ClassMethodNames = {
[K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;
}[keyof T];
class M {
val!: string
fnDat!: (str: string, num: number) => Date
fnNum!: (num: number) => number
fnStr!: (str: string) => string
cheker<
MethodName extends ClassMethodNames
>(
methodName: MethodName,
method: this[MethodName]
) {
console.log(methodName, method)
}
constructor() {
// Should not produce type error
this.cheker("fnDat", (str: string, num: number) => new Date)
this.cheker("fnNum", (num: number) => num)
this.cheker("fnStr", (str: string) => str)
// Should produce type error
this.cheker("val", () => { }) // methodNameError (val is not a method)
this.cheker("fnDat", () => new Date) // argsError
this.cheker("fnDat", (str: string, num: number) => null) // returnTypeError
this.cheker("fnNum", (num: number) => "") // returnTypeError
this.cheker("fnStr", (str: string) => 10) // returnTypeError
this.cheker("fnNotExistsInM", () => { }) // methodNameError
}
}
//
const m = new M()
// Should not produce type error
m.cheker("fnDat", (str: string, num: number) => new Date)
m.cheker("fnNum", (num: number) => num)
m.cheker("fnStr", (str: string) => str)
// Should produce type error
m.cheker("val", () => { }) // methodNameError (val is not a method)
m.cheker("fnDat", () => new Date) // argsError
m.cheker("fnDat", (str: string, num: number) => null) // returnTypeError
m.cheker("fnNum", (num: number) => "") // returnTypeError
m.cheker("fnStr", (str: string) => 10) // returnTypeError
m.cheker("fnNotExistsInM", () => { }) // methodNameError
This current case has two problems, the first is that the method parameter does not consider the parameters of the received function, it only takes into account the return.
and it is not possible to use this method within the class itself.