Search code examples
javascripttypescriptfunctiontype-safetynarrowing

How to write typescript typeguard method for function type


export const isFunction = (obj: unknown): obj is Function => obj instanceof Function;
export const isString = (obj: unknown): obj is string => Object.prototype.toString.call(obj) === "[object String]";

I want to write isFunction method - similar to isString, but typescript/eslint gives me an error:

Don't use `Function` as a type. The `Function` type accepts any function-like value.
It provides no type safety when calling the function, which can be a common source of bugs.
It also accepts things like class declarations, which will throw at runtime as they will not be called with `new`.
If you are expecting the function to accept certain arguments, you should explicitly define the function shape  @typescript-eslint/ban-types

Is there any way to do this?

P.S. Here is the answer:

export const isFunction = (obj: unknown): obj is (...args: any[]) => any => obj instanceof Function;

Solution

  • Well, the warning is clear... You can detect that you have a function, but you can't infer much about parameters/arity/return-type. That info just isn't available at run-time. It tells you that you can't be certain about how to call the function, or what it returns (at build time).

    If it's a risk you feel confident about, disable the warning.

    // tslint:disable-next-line: ban-types on the line above.

    Alternatively, type (...args:any[]) => any might be a good stand-in for Function, but a function of this type is no more type-safe than before.