Function Type & Callback In TypeScript

Function Type & Callback In TypeScript

What if we could use functions as a special type? Let me make my point clearer.Consider the following two functions:

function add(n1: number, n2: number): number {
  return n1 + n2;
}
function printResult(num: number): void {
  console.log('Result: ' + num);

Now suppose we have a variable as follows:

let combineValues;

In such a case, the type of combineValues ​​variable is of any type, but as I said, any is not very useful, so I want to do something like this:

combineValues = add;

That is, put the add function in combineValues. As you know, in JavaScript, we can do something like this and even execute this variable as a function:

let combineValues;
combineValues = add;
console.log(combineValues(8, 8));

If we compile this code with the command tsc app.ts and open the code in the browser, we will get the number 16. The problem is that currently the combineValues ​​variable is of type any so it accepts any value, even if we give it a number:

let combineValues;
combineValues = add;
combineValues = 5;
console.log(combineValues(8, 8));

The code above compiles without error, but we encounter an error in the browser because we made a logical mistake. By assigning the number 5 to combineValues, we have turned it into a normal variable that has the number 5 in it, and obviously such a variable cannot be implemented and we receive an error. To solve this problem, you can set the variable type to function:

let combineValues: Function;
combineValues = add;
combineValues = 5;
console.log(combineValues(8, 8));

By doing this in TypeScript, we immediately get an error that tells us that the number 5 is not a function. So this solves our problem, but it is still not a perfect method because Function means any function! In other words, by doing this, the following code will be allowed:

let combineValues: Function;
combineValues = add;
combineValues = printResult;
console.log(combineValues(8, 8));

Now, if we compile the code and open the browser, the result will be as follows:

Result: 8
undefined

Because printResult takes only one parameter, but we have set it to combineValues ​​and then given two parameters to combineValues! The typescript can't get any error from our code because we only set the Function type for it and printResult is also a function.

Our solution is function types:

let combineValues: () => number;

As you can see, this syntax is very similar to arrow functions, but it has nothing to do with them. By putting the parenthesis sign and then the arrow sign, we say that the combineValues ​​type is supposed to be a function (of course, a function that does not accept any parameters) and then we specify its output or return by adding number, which here is number.

Our function takes parameters, so we need to add these parameters to it:

let combineValues: (a: number, b: number) => number;
combineValues = add;
combineValues = printResult;

Now I have determined that combineValues ​​takes a function that has two parameters and both are numbers and finally returns a number. It is also not necessary that the names of these parameters are exactly the same as the main function, but anything (such as a and b) can be placed instead. By doing this, the second line (assignment add) will be fine, but for the third line (assignment printResult) we will encounter an error because our definition does not match printResult (two arguments in our definition instead of one argument in printResult and also return type of void type in printResult against number in our definition).

We can implement the same logic for callback functions. For example, consider the following function:

function addAndHandle(n1: number, n2: number, cb) {
  const result = n1 + n2;
  cb(result);
}

The third parameter of this function is cb or callback and it is supposed to be a function that is executed inside our function and receives the result value. Now, with the same logic as before, we can specify the type of callback explicitly:

function addAndHandle(n1: number, n2: number, cb: (num: number) => void) {
  const result = n1 + n2;
  cb(result);
}

That is, cb requires a number as its argument and returns void. why void? Because I want cb to execute the console.log statement, so it will not have any return statement. If you want cb to do more things and return something, you can change the above code. Now we can simply call it:

addAndHandle(10, 20, (result) => {
  console.log(result);
});

As you can see, I've given it an arrow function for the third parameter (note that this is really a function and not a type - it doesn't have a colon) which console.logs the value of the first two parameters. Now, if we go to the browser after compiling the code, we will see the output 30, which is the correct value.

Of course, the interesting point here is that if we write cb with the return statement, no error will be given to us:

addAndHandle(10, 20, (result) => {
  console.log(result);
  return result;
});

We specified above that cb should output void, so why doesn't it give us an error for return? Because we specified void in the addAndHandle function, which means that we have nothing to do with the cb output in the addAndHandle function, so void here means the output of the cb function in the addAndHandle function is not important to us. In simpler language, in such a case, void does not say that the cb function does not return anything, but it says that if a value is returned, it does not matter to us (in addAndHandle, of course).

H2
H3
H4
3 columns
2 columns
1 column
Join the conversation now
Logo
Center