How do I let TS compiler know a method is in an object?
I have a function, purpose of that is check a function is in an object, my expecting is if hasFunction returns true, that means function exist in object that I'm checking, and typescript compiler stop giving me error:
function hasFunction(obj: any, func: string) {
if (func in obj && (typeof obj[func] === "function"))
return true;
return false;
}
I tried to use it, but received an error:
function callMyFunc(obj: object) {
if (hasFunction(obj, "myFunc")) {
obj.myFunc();
}
}
// error: Property 'myFunc' does not exist on type 'object'.
I tried something like that, but 'in' is not a valid syntax:
function hasFunction(obj: any, func: string): func in obj
so what can I do to let compiler know that function exist on object?
CodePudding user response:
Your function needs to be generic over func
. You can store its literal type in a generic type K
. Now we only need a type predicate, so that the caller knows that obj
has a key K
which holds a function.
For the function type, you have to choose the right type for your needs. I went with the "unsafe" any
approach. In the type guard, you can't really check parameter and return types of the function because they don't exist at runtime. So you might as well just type them as unknown
.
function hasFunction<K extends string>(obj: any, func: K): obj is {
[Key in K]: (...args: any) => any
} {
return func in obj && (typeof obj[func] === "function")
}