In TypeScript, it is possible to define the structure of a function using an interface by defining:

  • the type of arguments the function can have and
  • the type of return value a function can have.

In this article, we will look at how to declare an interface as a function type.

interface Sum {
  (a: number, b: number): number;
}

let sum: Sum = (a: number, b: number) => a + b;

console.log(sum(1, 2)); // 3

In the above example, we have an interface Sum that defines an anonymous function that takes two arguments and returns a number type. To use this interface as a function type, we create a variable sum that is of type Sum and is equal to a function that takes two parameters as described in the Sum interface and returns the sum of two numbers which is of type number.

If sum does not follow the interface definition, TypeScript will throw an error. For example,

// NOT ALLOWED
let sum: Sum = (a: number, b: number) => "sum"; // Type '(a: number, b: number) => string' is not assignable to type 'Sum'. Type 'string' is not assignable to type 'number'.

In this case, we are returning a string that is not as per the definition of interface Sum. TypeScript will throw an error, Type '(a: number, b: number) => string' is not assignable to type 'Sum'. Type 'string' is not assignable to type 'number'.

Let’s look at some more examples,

interface Greet {
  (message: string): string;
}

let dog: Greet = (message: string) => message;

console.log(dog("Woof Woof")); // Woof Woof

Another example, with return type as boolean.

interface Positve {
  (num: number): boolean;
}

let checkPositive: Positve = (a: number) => a > 0;

console.log(checkPositive(100)); // true
console.log(checkPositive(-3)); // false

You can write the above function as a named function.

interface Positve {
  (num: number): boolean;
}

let checkPositive: Positve = function greaterThanZero(a: number) {
  return a > 0;
};

console.log(checkPositive(100)); // true
console.log(checkPositive(-3)); // false