All You Need to Know About Typescript Function Type

December 20, 2022
Uncle Big Bay
React.js

The Fastest Way to Build React UI

Convert Figma designs to production-ready React.js code. Build stunning apps and landing pages faster than your peers and competitors.

Introduction

Functions are the building blocks of an application. They’re a piece of code wrapped in a block to be reusable as a whole instead of repeating the piece of code over and over again when they’re needed.

In this article, we’re going to take a look at the TypeScript Function Type, how functions are created and how they work in TypeScript.

This article also assumes you have a working knowledge of JavaScript functions and variables which you can find here and a basic understanding of TypeScript.

Check out CopyCat, an AI-powered plugin to convert your Figma design to Tailwind CSS while you focus on the business logic of your App.

What is TypeScript Function Type?

Functions are first-class objects in JavaScript that expect parameters during declaration and accept arguments during invocation (when they’re called).

JavaScript functions are like procedures, they contain a set of instructions to be executed or invoked when an event is been triggered.

TypeScript Function Syntax

TypeScript functions are similar to vanilla JavaScript function syntax, except for their extra type-checking functionalities. Functions can be declared in multiple ways and the most common way to declare functions in TypeScript (same as JavaScript) are:

All these forms of creating functions are syntactical sugar to one another, or an alternative with deliberate limitation of usage. You can read more about JavaScript functions and their differences here.

Creating a Function Type in TypeScript

Given that we are to create a TypeScript function sum that adds up two numbers and returns the answer i.e 1 + 2 = 3.

Our function must be able to type-check the following conditions:

  • Accept the first and second numbers as a type of number only, i.e 1 and 2 must be a type of number.
  • Return a type number as the result, i.e 3 must be a type of number as well.

Function Declaration in TypeScript

The common and basic way to create a function in TypeScript is through the global type function keyword. A function declaration is also referred to as a function statement or normal function in JavaScript.

The expression above can be created in TypeScript using the function declaration as follows:

function sumTwoNumbers(a: number, b: number): number{
    let result = a + b
    return result
}

From the code above; the sumTwoNumbers function type accepts only two variables of the type number and should only return a type of number as the result of summing the two numbers as written in the function body.

Function Expression in TypeScript

A function expression is somewhat similar to a function declaration. However, it allows us to create functions in different ways such as; an anonymous function expression, a named function expression, and an immediately invoked function expression (IIFE).

TypeScript Anonymous Function

An anonymous function expression can be created in TypeScript as follows:

const sumTwoNumbers = function(a: number, b: number): number{
    let result = a + b
    return result
}

TypeScript Named Function Expression

A named function expression can be created in TypeScript as follows:

const result = function sumTwoNumbers(a: number, b: number): number{
    let result = a + b
    return result
}

TypeScript Immediately Invoked Function Expression (IIFE)

An immediately invoked function expression (IIFE) can be created in TypeScript as follows:

(function(a: number, b: number): number{
    let result = a + b
    console.log(result)
    return result
})(1, 2)

Arrow Function Expression in TypeScript

Arrow functions are new features in JavaScript Es6 and they can be used in TypeScript as well. We can create the sum function using the TypeScript arrow function as follows:

const sumTwoNumbers = (a: number, b: number): number =>{
    let result = a + b
    return result
}

Arrow functions can also be created as an immediately invoked function expression (IIFE) in TypeScript, as written below:

((a: number, b: number): number =>{
    let result = a + b
    console.log(result)
    return result
})(1, 2)

What is this expression? Check it out here.

TypeScript Function Invocation

Instructions in a function will only be executed when it’s being invoked or called. “Invoking a function” also means “calling a function”, and this causes the instruction code within the function block to get executed.

All types of functions discussed earlier (apart from IIFE), both in vanilla JavaScript, TypeScript, or other JavaScript frameworks or libraries are invoked/called in the same manner.

Below is an example of invoking function types in TypeScript:

doSomething()

The parentheses () declared in front of the function name are what invoke the function.

Function Arguments in a TypeScript function

Arguments are ways in which values are passed to a function, which are accessible in the function via its declared parameters. When a function is invoked, we can pass multiple arguments separated by commas to it.

The function sumTwoNumbers written earlier can be invoked with the two required parameters separated by commas as follows:

sumTwoNumbers(1, 2)

Always ensure there is a parameter declared for each argument you’re passing to a function.

Rest Arguments in a TypeScript function

The rest operator is a new feature in JavaScript Es6, it allows us to spread multiple values into an array and also to unwrap the values in an array stand-alone.

Given that we have an array of number-type arguments to be passed into a function like this:

const arrayOfNumbers = [1,2,3,4,5,6,7,8]

We can make use of the rest argument syntax to pass the individual arguments into the function as follows:

numbers(...arrayOfNumbers)

The above code is also the same as:

numbers( 1,  2,  3,  4,  5,  6 , 7 , 8)

The rest operator will automatically unwrap each item in the array for us. You can learn more about the rest operator from the video below:

Function Parameters in a TypeScript function

Parameters are one of the fundamental concepts that make JavaScript functions reusable and dynamic. We can define a parameter as a variable declared in parentheses when a function is created.

function doSomething(parameter_1, parameter_2){}

Function parameters allow us to have access to the values passed as arguments to a function when it has been called. Any valid JavaScript datatype can be expected as a parameter.

Optional Parameters in a TypeScript function

Sometimes we want some parameters to be optional, let’s say we want to create a function that sums three numbers, the first and second numbers are required while the third number is optional.

We can create this in TypeScript as follows:

function sumThreeNumbers(a:number, b:number, c?:number){
    if(c) return a + b + c
    return a + b
}

console.log(sumThreeNumbers(1, 2)) // Output: 3
console.log(sumThreeNumbers(1, 2, 3)) // Output: 6

If the parameter c is not marked as optional then the TypeScript function throws the following errors:

You can learn more about the TypeScript optional parameter from the video below:

Rest Parameters in a TypeScript function

The rest parameter is a new feature introduced in JavaScript Es6, it allows us to handle indefinite arguments passed to a function during invocation.

Given that we have a function that prints out all the numbers passed to it during invocation, the issue the rest operator will address for us is handling all other arguments we didn’t declare a parameter for as an array (since we don’t know the number of numbers that will be passed to the function when called).

Additionally, the above statement can be written in TypeScript as follows:

function numbers(a:number, b:number, ...rest: Array<number>){
    const number_1 = a
    const number_2 = b
    const other_numbers = rest.map(r=>r)

    console.log(number_1, number_2, ...other_numbers)
}

numbers(1, 2) // [LOG]: 1,  2 
numbers(1, 2, 3, 4, 5 ,6) // [LOG]: 1,  2,  3,  4,  5,  6

It is important to note the following about the rest operator:

  • The rest operator must come last in the function parameter list.
function sample1(...rest: Array<number>, a:number, b:number){} // ❌
function sample2(a:number,...rest: Array<number>, b:number){} // ❌
function sample3(a:number, b:number, ...rest: Array<number>){} // ✅
  • The rest operator must be a type of Array of the same type or will be a type of any[] by default.
function sample3(a:number, b:number, ...rest: Array<number>){} // ✅
function sample3(a:number, b:number, ...rest){} // any[]

Writing clean code: Learn how to avoid too many arguments in a function here.

Default Parameters in a TypeScript function

In a function, we can assign a default value to a named parameter, a process known as variable initialization. This value will then be used if no value is passed as an argument during the function call.

function welcome(name = "user"){
    return `You're welcome ${name}`
}

console.log(welcome()) // [LOG]: "You're welcome user" 
console.log(welcome("Sam")) // [LOG]: "You're welcome Sam"

TypeScript Function Return Types

When a function is created, then it is expected to return a value of any valid data type in TypeScript. A return type in TypeScript is the value type that is returned from a function.

How to Specify a Return Type in a TypeScript Function?

Below is the syntax for specifying a return type in a TypeScript function:

function myFunction(): returnType{
   return returnType
}

Where returnType can be a string, number, object, function, object or any TypeScript-supported data type.

What is the default Return Value of a TypeScript Function?

The default return value of a TypeScript function is undefined which is the same as JavaScript functions. When a function is declared without a specified return data type statement, then an undefined is returned.

However, the value of this parameter is returned as the default value in the case of a constructor.

What is Void in TypeScript?

The type void statement can be used to declare a function that does not return values or anything, this keyword will prevent TypeScript from throwing an error. The void type can accept undefined or null as a value.

What does `() => void’ mean in TypeScript?

The syntax ()=>void means a function with no parameter that returns no value.

Given that we have a function that accepts a print callback function and the year of birth, then calculate the age as of the year 2022.

function ageCal_2022(cb:(age:number)=>void, yob:number){
    const age = 2022 - yob
    cb(age)
}

We set the callback function to accept a parameter of the type age and return nothing since its only task is to print the new age.

The printAge callback function will look like this:

function printAge(age:number){
    console.log(age)
}

Now, we can invoke the ageCal_2022 function with the printAge function and a year of birth as arguments like this:

ageCal_2022(printAge, 1999) // Output 23

Returning a String type in a TypeScript function

Below is how to declare a string type parameter and how to return a string in the TypeScript function:

function myFunc(a:string): string{
    return a
}

Returning a Number type in a TypeScript function

Below is how to set a number type parameter and how to return a number type in a TypeScript function:

function myFunc(a:number): number{
    return a
}

Returning an Object type in a TypeScript function

Below is how to declare an object type parameter and how to return an object type in a TypeScript function.

function myFunc(a:object): object{
    return a
}

or create an interface for the return object structure like this:

interface MyFunc {
    status: string,
    code: number
}

function myFunc(statusMessage:string, statusCode: number): MyFunc{
    return {status: statusMessage, code: statusCode}
}

console.log(myFunc("success", 200)) 
// Output: { "status": "success",  "code": 200 }

This will ensure the data type of the keys-values in the returned object matches the ones within the MyFunc interface. TypeScript will throw an error in this case.

Returning Unknown type in a TypeScript function

The unknown keyword is used to specify the return type of data we’re not sure of, this is useful for safer typing, as the unknown type cannot be assigned to any other thing apart from itself and the any type.

Given that we have a function that accepts a name of a type string and age of an unknown type, the function also returns an unknown data type.

We can write this as follows:

function myFunc(name: unknown, age: unknown): unknown{
    return [name, age]
}

console.log(myFunc("Sam", "23")) // [LOG]: ["Sam", "23"]

Returning Any type in a TypeScript function

Similar to the unknown keyword, we make use of the any keyword to make TypeScript ignore type checking for the parameter or return type of a function.

function myFunc(name: any, age: any): any{
    return [name, age]
}

console.log(myFunc("Sam", "23")) // [LOG]: ["Sam", "23"]

Returning a Never type in a TypeScript function

Never is a type in TypeScript, it’s useful to declare a return type for a variable, parameter, or the return type of a function that will never return to its caller. A function with never return type must not have a reachable endpoint, it must either never return or runs continuously (loop).

function writeAppWithoutStackOverFlow(): never{
    while(true){
        console.log("You cannot do that!!!")
    }
}

console.log(writeAppWithoutStackOverFlow()) // Loop

Returning a Function type in a TypeScript function

A function can also return a function, and we can declare this in TypeScript by using the Function keyword as shown below:

function addOne(a:number): Function{
    return print(a+1)
}

function print(a:any){
    console.log(a)
    return a
}

addOne(100) // [LOG]: 101

TypeScript Guide for Function Return Types

  • Use the return statement within the function body to return a value.
  • You can return any data type within the function body such as a string, number, object, and any, etc.
  • Use the colon symbol : to define the parameter and its data type as key-value pair i.e parameter: type.
  • The type of the returned value within the function body must match the return type declared to avoid a compile-time warning.

Also, check out more TypeScript dos and don’t from here.

Function Overloads in TypeScript

TypeScript offers a concept known as function overloads where two or more functions can have the same name but different return types and parameter data types of the same number and can be used independently.

The concept can be divided into three

  • Function signatures: This is where we declare the data type and return type of the functions. We can have as many function signatures as far as the data types are not the same. Also, note that each of the function signatures must have the same number of parameters.
  • Function body: This is where the main logic of the function is declared and evaluated for the function signatures.
  • Function invocation: This is where the function is called with respective data types as declared in their function signatures.
// Function signatures
function addTogether(a: string, b:string): string; 
function addTogether(a: number, b:number): number;

// Function body
function addTogether(a:any, b:any):any{
    return a + b
}

// Function invocation
console.log(addTogether(1,2)) // [LOG]: 3 
console.log(addTogether("Mr. ", "Sam")) // [LOG]: "Mr. Sam"

Learn more about function overload here.

Wrapping Up

TypeScript functions are similar to JavaScript functions and should be familiar to those with a JavaScript background. We discussed the TypeScript function’s type, parameters, and arguments in this article, as well as how to use the rest in both parameters and arguments.

Finally, you can find more articles like this on our CopyCat blog. CopyCat is a tool that converts your Figma files to a ready-to-use React project, saving you over 35% of development time. Copycat can be found here.

Interesting Reads From Our Blogs

Happy Coding 👨🏽‍💻

Related Articles

  • React.js

    All You Need to Know About React Props

    What are React Props? Props represent a component's " properties, " and it’s similar to the concept of parameters and arguments in JavaScript functions. Props enable us to share dynamic data from one component to another. How Props works in…

    October 31, 2022
  • React.js

    React Query Tutorial: Getting Started with Fetching Data and State Management with…

    Introduction Building a full-stack application is incomplete until when you can exchange data between different components. Fullstack application refers to being able to carry out the CRUD operations. The most important aspect of a full-stack application is the ability to…

    August 26, 2022

Convert Figma To React

Convert Figma designs to production-ready React.js code. Build stunning apps and landing pages faster than your peers and competitors.

Convert Design to Code