Learn ASP.NET Core 3.1 with mini project : MVC, Razor Pages, Web API, Entity Framework Core, and Blazor. Hands-on online training course starting in August 2020. Click here to know more.

Essentials of TypeScript Functions

In the previous article of this series you learned about TypeScript variables and their data types. A common JavaScript construct is function. And TypeScript has some interesting features to offer when it comes to creating functions. Specifically this article covers function return types, optional parameters, default parameters, rest parameters, and callbacks.

So, let's get going. I am going to use a variation of the temperature convertor example in this article. So make sure that you are familiar with it from the previous part of this series.

Begin by adding Functions.ts and Functions.html files into the TypeScript folder. You will write the following TypeScript inside Functions.ts file.

Indicate function return type

Earlier you create the convert() function that takes a numeric value and ConversionType parameters as the input. However, the function didn't return any value to the caller. Here, I am going to split the convert() function into three independent functions namely convertToCelsius(), convertToFahrenheit(), and showResult().

The convertToCelsius() function is shown below:

function convertToCelsius(value: number): number {
    let tempInC: number;
    tempInC = (value - 32) * 5 / 9;
    return tempInC;
}

The convertToCelsius() function takes a numeric input as before and returns the temperature value in Celsius. Notice the code marked in bold letters. After the function parameter list there is colon (:) followed by the return type of the function. The return type could be any valid data type (inbuilt or custom) including void.

Inside, the code applies a formula that converts a temperature value to Celsius and stores the result into tempInC local variable. This value is then returned from the function. You could have done all of this into a single line of code but here deliberately I am using a bit verbose code for clear understanding.

The convertToFahrenheit() function looks similar except that it converts a temperature value into Fahrenheit.

function convertToFahrenheit(value: number): number {
  let tempInF: number;
  tempInF = value * 9 / 5 + 32;
  return tempInF;
}

You might want to output the result of the conversion on to the page. The showResult() function does that and is shown below:

let showResult = function (result: number): void {
    document.getElementById("msg").innerHTML 
    = "<h2>Result : " + result + "</h2>";
}

This function uses an alternate approach to defining a function. Instead of creating a named function such as convertToCelsius() and convertToFahrenheit(), it creates an anonymous function that accepts a numeric parameter and returns nothing (void). Inside, the code grabs the msg <div> element and sets its innerHTML property to the result.

This anonymous function can be called using the showResult variable like this:

showResult(100);

Once these three functions are ready you can modify the convert() function to use them. The modified convert() function is shown below:

function convert(value: number, 
conversionType: ConversionType): void {
    let result: number;
    if (conversionType == 
ConversionType.CelsiusToFahrenheit) {
        result = convertToCelsius(value);
    }
    else {
        result = 
convertToFahrenheit(value);
    }
    showResult(result);
}

This code is quite straightforward and hence I won't go into more details.

To test the code you wrote so far, add this markup to the Functions.html file.

<body onload="DoWork()">
    <div id="msg"></div>
    <script src="/TypeScript/Output/Functions.js">
    </script>
</body>

The DoWork() function needs to added to the Functions.ts and is shown below:

function DoWork() {
  convert(100, ConversionType.CelsiusToFahrenheit);
}

And here is a sample output:

Optional Parameters

The convert() function takes two required parameters - numeric value and ConversionType. If you want to skip setting the ConversionType explicitly, you can make it an optional parameter. Once you mark it as an optional parameter you are not required to supply its value while calling the convert() function. Since this is now an optional parameter, you must take into account a possibility of missing ConversionType in your code. You might use some default value in case ConversionType is missing or change the course of execution as needed.

The following code shows how a function parameter can be marked optional.

function convert(value: number, 
conversionType?: ConversionType): void {

}

Notice that conversionType parameter is now suffixed with ? character. This indicates that it's an optional parameter.

To account for this missing value you can perform the following check in your code:

if (typeof conversionType === 'undefined') {
    conversionType = ConversionType
.CelsiusToFahrenheit;
}

If you don't pass a ConversionType while calling the convert() function, the value of conversionType parameter will be undefined. And you assume the conversion type to be CelsiusToFahrenheit.

The completed convert() is shown below:

function convert(value: number, 
conversionType?: ConversionType): void {
    let result: number;

    if (typeof conversionType === 'undefined') {
        conversionType = 
ConversionType.CelsiusToFahrenheit;
    }

    if (conversionType == 
ConversionType.CelsiusToFahrenheit) {
        result = convertToCelsius(value);
    }
    else {
        result = convertToFahrenheit(value);
    }

    showResult(result);
}

Optional parameters must appear at the end of the parameter list in a function signature.

You can call the convert() function like this:

function DoWork() {
    convert(100);
}

As you can see, this time you haven't passed a ConversionType.

Default parameters

Many a times optional parameters have some default value. In the parameter is missing this default value is used. One way to accomplish this is to use optional parameters as discussed above. An easy approach is to assign a default value. The following code shows the convert() function that uses a default value for ConversionType.

function convert(value: number, conversionType: 
ConversionType = ConversionType.CelsiusToFahrenheit)
: void {
    let result: number;

    if (conversionType == 
ConversionType.CelsiusToFahrenheit) {
        result = convertToCelsius(value);
    }
    else {
        result = convertToFahrenheit(value);
    }

    showResult(result);
}

As you can see, conversionType is no longer an optional parameter but has a default value assigned to it. If you don't supply a ConversionType while calling convert() then this default value will be used. Since a default value is specified in the function signature itself, you don't need the "undefined" check inside the code.

Rest parameters

At times you are unaware of the number of parameters to be passed to a function. For example, so far the current() function is converting just one temperature value. What if you want to pass 2 or more values. Additionally, you might not know how many values are to be passed. Sometimes 2, sometimes 3, and sometimes 5. In such cases Rest parameters come handy. They indicate "rest" of the parameters being passed to the function. If you are familiar with C# param array then Rest parameters should look familiar to you.

This is how convert() can be modified to use Rest parameters.

function convert(conversionType: ConversionType, 
...values: number[]): number[] {

    let results: number[] = new Array();

    for (let item in values) {
        if (conversionType == 
ConversionType.CelsiusToFahrenheit) {
            results.push(
convertToFahrenheit(values[item]));
        }
        else {
            results.push(
convertToCelsius(values[item]));
        }
    }
    showResults(results);
)

Notice the code shown in bold letters. This is how you indicate a Rest parameter. Since Rest parameters must appear at the end of a function signature, ConversionType is made the first parameter and ...values as the second parameter. The varying number of values passed while calling convert() are captured as a number array (since a temperature value is number). The three dots syntax marks value to be a Rest parameter.

Inside, the code creates a new numeric array to store the converted values. This array is initialized using Array object.

A for..in loop of TypeScript iterates through the values array. Every iteration converts a temperature value depending on ConversionType and pushes it to the results array using push() method.

To display the converted values on the page, you need showResults() function that accepts the results array. This function is shown below:

let showResults = function 
(results: number[]) {
    for (let item in results) {
        document.getElementById
("msg").innerHTML += 
"<h2>" + results[item] + "</h2>";
    }
}

This code iterates through all the results and appends them to the msg <div> element.

You can now call convert() like this:

function DoWork() {
    convert(ConversionType.CelsiusToFahrenheit,
    100,200,300);
}

And here is the output:

Callback functions

Function parameters are not restricted to primitive data types or complex types. You can also pass a function as a parameter to another function. In JavaScript this is often done while using callback functions. TypeScript provides a better and strongly typed approach to passing such callback functions. Let's see how.

Suppose you want to accept a third parameter to the convert() function that accepts a callback function. This callback function is executed once the temperature conversion is done. A benefit of this approach is that you are not tied to showResult() function to display the result. You can decide what should happen upon calculating a temperature value while calling the convert() method. At times you may display it inside <div> element, at times you might display it in a popup, and at some other times you might pass the result to another function for further processing.

The modified signature of convert() is shown below:

function convert(value: number, 
conversionType: ConversionType, 
callback: (result: number) => void) {

    let result: number;
    if (conversionType == ConversionType.
CelsiusToFahrenheit) {
        result = convertToFahrenheit(value);
    }
    else {
        result = convertToCelsius(value);
    }
    callback(result);
}

Notice the code shown in bold letters. The convert() function now has a third parameter called callback. Since this parameter is supposed to be a function, its "type" is a function. And the function signature is indicated using what is known as an arrow function. Here, the code indicates that the callback function should be a function that takes one numeric parameter and returns void.

Inside, after performing the necessary temperature conversion, the code invokes the callback function by passing the result value to it.

To call this version of convert() you can write the following code:

function DoWork() {
  convert(100, ConversionType.CelsiusToFahrenheit, 
  (result) => {
        document.getElementById
        ("msg").innerHTML = 
        "<h2>Result : " + result + "</h2>";
  });

Notice how the callback function is specified as an arrow function. You could have also used the following approach to call convert().

let callback = function(result:number):void {
  document.getElementById("msg").
  innerHTML = "<h2>Result : " + result + "</h2>";
}

convert(100, ConversionType.CelsiusToFahrenheit, 
callback);

You can read more about TypeScript functions in the official documentation here.

You can also watch the companion video to this article that shows everything discussed in the article:

That's it for now! Keep coding!!


Bipin Joshi is an independent software consultant, trainer, author, yoga mentor, and meditation teacher. He has been programming, meditating, and teaching for 24+ years. He conducts instructor-led online training courses in ASP.NET family of technologies for individuals and small groups. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Ajapa Yoga to interested individuals. To know more about him click here.

Get connected : Facebook  Twitter  LinkedIn  YouTube

Posted On : 13 April 2020


Tags : ASP.NET ASP.NET Core .NET Framework C# JavaScript Visual Studio


Subscribe to our newsletter

Get monthly email updates about new articles, tutorials, code samples, and how-tos getting added to our knowledge base.

  

Receive Weekly Updates