If you see the long reading time for this article, don't worry 😉. I have written this awesome😎 article with many code examples😃 (with some nice Meme😂 as well); it's not just theory🔥.
So, buckle up🚀. We will begin our incredible journey🛣
Functions
are the fundamental building blocks🏗 of an application. A function
is an action that performs a certain behavior like login the user, showing a list of items, requesting data from the server, and so forth. These actions together compose a system to solve various tasks🔥.
In mathematics, a function
is described as an object that produces an output when given an input(meh, why Mathematics here😆). While in programming we have two types✌️ of functions.
- A function that returns a value,
- or one that doesn’t return anything.
For instance, if you need the result like the sum of five numbers, we need to return the total value.
And if you need to print out a message to the console, a return type is not necessary.😺
Functions
To begin with, just as in JavaScript, TypeScript functions can be created both as a named function or as an anonymous function🎭.
To quickly recap what these two approaches look like in JavaScript:
// Named function 🤡
function display() {
console.log("Typescript is Awesome🔥");
}
display(); //Output: Typescript is Awesome🔥
// Anonymous function 🎭
let greeting = function() {
console.log("You are Awesome😎");
};
greeting(); //Output: You are Awesome😎
Calling a Function ☎️
A function
must be called so as to execute it (ofcos 😆). This process is termed as function invocation.
Syntax
Function_name()
The following example illustrates how a function
can be invoked −
function test() { // function definition
console.log("function called")
}
test() // function invocation 🔥
On compiling, it will generate the same JavaScript code.
function test() {
console.log("function called");
}
test(); // function invocation 🔥
It will produce the following output −
function called
Anonymous Function 🎭
Functions
that are not bound to an identifier (function name) are called anonymous functions
. These functions are dynamically declared at runtime.
Anonymous functions
can accept inputs and return outputs, just as standard functions do😆. An anonymous function is usually not accessible after its initial creation.
Variables can be assigned an anonymous function. Such an expression is called a function expression.
Syntax
var res = function( [arguments] ) { ... } ✅
Example ─ A Simple Anonymous function
var msg = function() {
return "hello world";
}
console.log(msg())
On compiling, it will generate the same code in JavaScript.😉
It will produce the following output −
hello world
Example ─ Anonymous function with parameters
var res = function(a: number,b: number) {
return a*b;
};
console.log(res(12,2)) // 24
The anonymous function
returns the product of the values passed to it.
Wuhuu, the main part 🥳
Typing The Function 🤩
Like JavaScript, you use the function
keyword to declare a function in TypeScript:
function name(parameter: type, parameter:type,...): returnType {
// do something
}
Let’s see the following add()
function example:
function add(a: number, b: number): number {
return a + b;
}
In this example, the add()
function accepts two✌️ parameters with the number
type.
When you call the
add()
function, the TypeScript compiler will check👨🏭 each argument passed to thefunction
to ensure that they arenumbers
.In the
add()
function example, you can only pass numbers into it, not the values of other types🚨.
The following code will result in an error because it passes two strings instead of two numbers into the add()
function:
let sum = add('10', '20'); ❌
Error:
error TS2345: Argument of type '"10"' is not assignable to parameter of type 'number'
The : number
after the (parentheses) indicates the return
type. The add()
function returns a value of the number type in this case.
When a function
has a return type, the TypeScript compiler checks👨🏭 every return statement against the return type to ensure that the return value is compatible with it👍.
If a function
does not return a value, you can use the void
type as the return type. The void
keyword indicates that the function
doesn’t return any value👻.
For example:
function echo(message: string): void {
console.log(message.toUpperCase());
}
The void
prevents🗡 the code inside the function from returning a value and stops the calling code from assigning the result of the function to a variable.
When you do not annotate the return
type, TypeScript will try to infer an appropriate type.
For example:
function add(a: number, b: number) {
return a + b;
}
In this example, the TypeScript compiler tries to infer the return
type of the add()
function to the number
type, which is expected😆.
More infer
stuff on next section😉
Inferring the types 😃
With the example before this, you may notice that the TypeScript compiler can figure out the type
even if you only have types on one side of the equation:
// The parameters 'x' and 'y' have the type number
let myAdd = function (x: number, y: number): number {
return x + y;
};
// myAdd has the full function type
let myAdd2: (baseValue: number, increment: number) => number = function (x, y) {
return x + y;
};
Compare the Typescript with Javascript result😎
Lambda Function => ƛ
Lambda
refers to anonymous functions in programming. Lambda functions
are a concise mechanism to represent anonymous functions. These functions are also called as Arrow functions.
Lambda Function - Anatomy
There are 3 parts to a Lambda function
−
Parameters = A function may optionally have parameters
The fat arrow notation/lambda notation (=>) − It is also called as the goes to the operator
Statements − represent the function’s instruction set
Lambda Expression
It is an anonymous function expression that points to => a single line of code🚨. Its syntax is as follows −
( [param1, parma2,…param n] )=> statement;
Example: Lambda Expression
var foo = (x: number)=> 10 + x
console.log(foo(100)) // outputs : 110
The program declares a lambda expression function. The function
returns the sum of 10 and the argument passed.
On compiling, it will generate the following JavaScript code.
//Generated by typescript 4.0.2
var foo = (x) => 10 + x;
console.log(foo(100)); //outputs 110
Lambda Statement
Lambda statement
is an anonymous function declaration that points to a block of code.🚨 This syntax is used when the function body spans multiple lines. Its syntax is as follows −
( [param1, parma2,…param n] )=> {
//code block
}
Example: Lambda statement
var foo = (x: number)=> {
x = 10 + x
console.log(x)
}
foo(100) // 110. ✅
The function’s reference is returned and stored in the variable foo.
Awesome 🔥
Optional and Default Parameters 😋
The number of arguments given to a function
has to match the number of parameters the function expects.
function buildName(firstName: string, lastName: string) {
return firstName + " " + lastName;
}
let result1 = buildName("Amirul"); // ❌ error, too few parameters
let result2 = buildName("Amirul", "Asyraf", "Awesome");
// ❌ error, too many parameters
let result3 = buildName("Amirul", "Asyraf"); // ✅ ah, just right
OPEN THIS LIVE EXAMPLE FOR BETTER ERROR EXPLANATION
In JavaScript, every parameter
is optional😃, and users👨💼 may leave them off as they see fit(like optional email field😉). When they do, their value is undefined
😬.
We can get this functionality in TypeScript by adding a ?
to the end of parameters
we want to be optional.
Code please 😑 Ok2
Example: Optional Parameters
function disp_details(id: number,name: string,mail_id?: string) {
console.log("ID : ", id);
console.log("Name : ", name);
if(mail_id!= undefined)
console.log("Email Id : ", mail_id);
}
disp_details(123, "Asyraf"); 😎
disp_details(111, "meh", "meh@hey.com");
The above example declares a parameterized function. Here, the third parameter, i.e.,
mail_id
is an optional parameter.If an optional parameter is not passed a value during the function call, the parameter’s value is set to
undefined
😐.The function prints the value of
mail_id
only if the argument is passed a value.
The above code will produce the following output −
ID : 123
Name : Asyraf
ID: 111
Name : meh
Email Id : meh@hey.com 👈
In TypeScript, we can also set a value😺 that a parameter
will be assigned if the user does not provide one🔥, or if the user passes undefined
in its place. These are called default-initialized
parameters. I show you in the code version😉.
Example: Default parameters
function calculate_discount(price: number,rate: number = 0.50) {
var discount = price * rate;
console.log("Discount Amount: ", discount);
}
calculate_discount(1000)
calculate_discount(1000, 0.30)
Its output is as follows −
Discount Amount : 500 🔥
Discount Amount : 300 🔥
another exp 🤩
function buildName(firstName: string, lastName = "Awesome") {
return firstName + " " + lastName;
}
let result1 = buildName("Amirul");
// ✅works correctly now, returns "Amirul Awesome"
let result2 = buildName("Asyraf", undefined);
// ✅still works, also returns "Asyraf Awesome"
let result3 = buildName("Bob", "Adams", "Sr."); // ❌error, too many parameters
let result4 = buildName("Amirul", "Asyraf"); // ✅ah, just right
OPEN THIS LIVE EXAMPLE FOR BETTER ERROR EXPLANATION
Rest Parameters 🎶
TypeScript introduced rest
parameters to accommodate n
number of parameters easily🥳.
When the number of parameters that a function
will receive is not known🤔 or can vary, we can use rest parameters. In JavaScript, this is achieved with the arguments
variable. However, with TypeScript, we can use the rest parameter
denoted by the ellipsis ...
Example: Rest Parameters
function addNumbers(...nums: number[]) {
var i ;
var sum: number = 0;
for(i = 0; i < nums.length ; i++) {
sum = sum + nums[i];
}
console.log("sum of the numbers", sum)
}
addNumbers(1,2,3)
addNumbers(10,10,10,10,10)
another exp 🤩
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
// employeeName will be "Lucas Samuel Peter MacKinzie" 🔥
let employeeName = buildName("Lucas", "Samuel", "Peter", "MacKinzie");
Remember, rest parameters
must come last in the function definition🚨, otherwise the TypeScript compiler will show an error😆.
The following is not valid.
function Greet(...names: string[], greeting: string) { // ❌Compiler Error
return greeting + " " + names.join(", ") + "!";
}
OPEN THIS LIVE PLAYGROUND TO SEE ERROR
Arrow Function =>
Fat arrow notations
are used for anonymous functions i.e for function expressions. They are also called lambda functions in other languages.
In this section, no more Theory😆 because I have explained that in the Lambda and Anonymous Function section...
So, more code examples🤩
Syntax:
(param1, param2, ..., paramN) => expression
Example: Fat Arrow Function
let sum = (x: number, y: number): number => {
return x + y;
}
sum(10, 20); //returns 30 ✅
Example: Parameterless Arrow Function
let Print = () => console.log("Hello TypeScript");
Print(); // Output: Hello TypeScript ✅
Furthermore, if the function
body consists of only one statement then no need for the {curly brackets} and the return keyword, as shown below.
let sum = (x: number, y: number) => x + y;
sum(3, 4); //returns 7 ✅
A class can include an arrow function as a property, as shown below.
Example: Arrow Function in Class Copy
class Employee {
empCode: number;
empName: string;
constructor(code: number, name: string) {
this.empName = name;
this.empCode = code;
}
display = () => console.log(this.empCode +' ' + this.empName)
}
let emp = new Employee(1, 'Asyraf'); 🤓
emp.display();
another Arrow function in a class example
Muahahaha😂
class Student {
studCode: number;
studName: string;
constructor(code: number, name: string) {
this.studName = name;
this.studCode = code;
}
showDetail = () => console.log("Student Code: " + this.studCode + '\nStudent Name: ' + this.studName)
}
let stud = new Student(101, 'Asyraf Awesome'); 🔥
stud.showDetail();
Output
Student Code: 101
Name: Asyraf Awesome 🔥
The Function Constructor
TypeScript also supports defining a function with the built-in JavaScript constructor called Function ()
. 🤩
Syntax
var res = new Function( [arguments] ) { ... }.
Example
var myFunction = new Function("a", "b", "return a * b");
var x = myFunction(4, 3);
console.log(x); // 12
The new Function()
is a call to the constructor which in turn creates and returns a function reference.🔥
On compiling, it will generate the same code in JavaScript.
Function Overloads
TypeScript provides the concept of function overloading
. You can have multiple functions with the same name but different parameter types and return type. However, the number of parameters should be the same.
function add(a: string, b: string): string;
function add(a: number, b: number): number;
function add(a: any, b: any): any {
return a + b;
}
add("Hello ", "Steve"); // returns "Hello Steve"
add(10, 20); // returns 30
In the above example, we have the same function add()
with two function declarations and one function implementation. The first signature has two parameters of type string
, whereas the second signature has two parameters of the type number
.
The last function should have the function implementation. Since the return type can be either string or number as per the first two function declarations, we must use compatible parameters and return type as any in the function definition.
It is a useful concept that can create abstract layers when dealing with functions with many behaviors🔥.
Let’s see an example of overload parameter
🤩:
// Create overloads
function runEngines(engine: { engine1: boolean; engine2: boolean });
function runEngines(engines: number);
function runEngines(engines: boolean);
function runEngines(x): any {
// If argument is number
if (typeof x === "number") {
console.log(`Run all ${x}`);
}
// If argument is an object
if (typeof x === "object") {
console.log(`Run eng1: ${x.engine1}, eng2: ${x.engine2}`);
}
// If argument is a boolean
if (typeof x === "boolean") {
let msg = x ? "Start all engines" : "Stop all engines";
console.log(msg);
}
}
// Invoke function
runEngines({ engine1: true, engine2: false }); // Output: Run eng1: true, eng2: false
runEngines(4); // Output: 4
runEngines(true); // Output Start all engines
As shown in the example above, the function runEngines()
use the typeof
keyword to check the argument type to define what operation to execute. Notice that the function function runEngines(x): any
must be defined last because it’s a universal function🌎 that represents all possibilities defined in the functions above😎.
Another Cool Example🤩
// Overloads
function padding(all: number);
function padding(topAndBottom: number, leftAndRight: number);
function padding(top: number, right: number, bottom: number, left: number);
// Actual implementation that is a true representation of all the cases the function body needs to handle
function padding(a: number, b?: number, c?: number, d?: number) {
if (b === undefined && c === undefined && d === undefined) {
b = c = d = a;
}
else if (c === undefined && d === undefined) {
c = a;
d = b;
}
return {
top: a,
right: b,
bottom: c,
left: d
};
}
Here the first three function headers are available as valid calls to padding:
padding(1); // Okay: all ✅
padding(1,1); // Okay: topAndBottom, leftAndRight ✅
padding(1,1,1,1); // Okay: top, right, bottom, left ✅
padding(1,1,1); // ❌ Error: Not a part of the available overloads
The Function/Method overloading is allowed when:
- The
function
name is the same - The number of parameters is different🚨 in each
overloaded function
. - The number of parameters is the same🚨, and their type is different🚨.
- All
overloads function
must have the same return type.
The last part 😍
This
keyword in Function
I will not explain it in this article🙏 because it makes this article too long🚀 to read tho😆.
Also, the explanation about this
keyword is too detailed🥺 to explain in this awesome article😃.
I will give you the link that you can learn about it awesomely👍
you will learn ;
- this
- this and arrow functions
- this parameters
this parameters in callbacks
Great 🤜🤛
Finish 🏁
Wuhuuu🥳
Thanks for finishing it 🙌
You're Awesome 😎
Bookmark and Share it 🤟
Another cool resources🤘
Muahhaha😂
note : I'm sorry🙏 for the long article as I want you to understand better and triple better than me🔥