Author: saqibkhan

  • Union

    TypeScript gives programs the ability to combine one or two types. Union types are a powerful way to express a value that can be one of the several types. Two or more data types are combined using the pipe symbol (|) to denote a Union Type. In other words, a union type is written as a sequence of types separated by vertical bars.

    Syntax: Union literal

    We use pipe symbol (|) to combine two or more types to achieve a union type in TypeScript −

    Type1 | Type2 | Type3 
    

    Union Type Variable

    We can define a variable of type union of different types. For example,

    let value:number|string|boolean;

    In the above example, we define a variable named value of union type. We can assign numeric, string or boolean value to the variable.

    Example: Union Type Variable

    In the example below, the variable’s type is union. It means that the variable can contain either a number or a string as its value.

    var val:string|number 
    val =12console.log("numeric value of val: "+val) 
    val ="This is a string"console.log("string value of val: "+val)

    On compiling, it will generate following JavaScript code.

    var val;
    val =12;
    console.log("numeric value of val: "+ val);
    val ="This is a string";
    console.log("string value of val: "+ val);

    Its output of the above example code is as follows

    numeric value of val: 12 
    string value of val: this is a string 
    

    Union Type and Function Parameter

    We can define a function with a parameter of union type. When you can call the function, you can pass the argument of any type of union type. For example,

    functiondisplay(name:string|string[]){// function body;}

    In the above code snippet, function display() has parameter of union type (string or string array). You can call the function passing argument either a string or an array of string.

    Example

    In the example below, we defined a function named disp with a parameter of union type.

    The function disp() can accept argument either of the type string or a string array.

    functiondisp(name:string|string[]){if(typeof name =="string"){console.log(name)}else{var i;for(i =0;i<name.length;i++){console.log(name[i])}}}disp("mark")console.log("Printing names array....")disp(["Mark","Tom","Mary","John"])

    On compiling, it will generate following JavaScript code.

    functiondisp(name){if(typeof name =="string"){
    
      console.log(name);}else{var i;for(i =0; i &lt; name.length; i++){
         console.log(name&#91;i]);}}}disp("mark");
    console.log("Printing names array....");disp(["Mark","Tom","Mary","John"]);

    The output is as follows

    Mark 
    Printing names array. 
    Mark 
    Tom
    Mary
    John 
    

    Union Type and Arrays

    Union types can also be applied to arrays, properties and interfaces. The following illustrates the use of union type with an array.

    Example

    The program declares an array. The array can represent either a numeric collection or a string collection.

    var arr:number[]|string[];var i:number; 
    arr =[1,2,4]console.log("**numeric array**")for(i =0;i<arr.length;i++){console.log(arr[i])}  
    
    arr =["Mumbai","Pune","Delhi"]console.log("**string array**")for(i =0;i<arr.length;i++){console.log(arr[i])}

    On compiling, it will generate following JavaScript code.

    var arr;var i;
    arr =[1,2,4];
    console.log("**numeric array**");for(i =0; i < arr.length; i++){
       console.log(arr[i]);}
    arr =["Mumbai","Pune","Delhi"];
    console.log("**string array**");for(i =0; i < arr.length; i++){
       console.log(arr[i]);}

    Its output is as follows −

    **numeric array** 
    1 
    2 
    4 
    **string array** 
    Mumbai 
    Pune 
    Delhi
    
  • Never

    The never type

    The never type in TypeScript represents the values that can never occur. For example, the return type of a function that throws an error is never.

    functionfuncName():never{// it throws an exception or never returns}

    You cannot assign a value to a variable of never type

    let x:never;
    x =10;// throw error

    The above TypeScript code snippet will throw the following errors

    Type 'number' is not assignable to type 'never'.
    

    You can use the never type as the return type of a function that never returns or always throws an exception.

    A function that never stops executing

    functioninfiniteLoop():never{for(;;){}}

    Another example of function that never stops executing

    functioninfiniteLoop():never{while(true){}}

    Variables also acquire the type never when narrowed by any type guards that can never be true.

    The never type is used when we have exhausted all possible value and we don’t have anything to assign.

    functioncheck(value:string|number){if(typeof value ==='string'){return"value is string";}else{return"value is number";}// here, not a string or number// "value" can't occur here, so it's type "never"}

    The never type is a subtype of, and assignable to, every type; however, no type is a subtype of, or assignable to, never (except never itself). Even any isnt assignable to never.

    You can annotate a variable with never type, but it is very uncommon

    functionshowError():never{thrownewError("Error message from function with never as return type.");}let x:never=showError();

    In the above Typescript code snippet, variable x is annotated with the never type. The variable x is assigned showError() function that itself has the never as return type.

    void vs. never

    In TypeScript, a variable of void type can store undefined as a value. On the other hand, never can’t store any value.

    let val1:void=undefined;let val2:never=undefined;// error: Type 'undefined' is not assignable to type 'never'.

    We know that if a function in TypeScript does not return any value, it returns undefined. We generally annotate the type of return type of such function with void. Look at the below example,

    functiongreet():void{console.log("Welcome to tutorials Point");}let msg:void=greet();console.log(msg);

    In the above example, we defined a function greet() that doesn’t return any value. When we call the function, the return value is undefined.

    On compiling, it will generate the following JavaScript code.

    functiongreet(){console.log("Welcome to tutorials Point");}let msg =greet();console.log(msg);

    The output of the above code is as follows

    Undefined
    
  • Any Type

    The any type in TypeScript is a specific type that can represent any value. It is generally used when a type of variable is unknown or not yet defined. The any type is useful when converting the JavaScript code to TypeScript.

    Any type is not a type in traditional sense. It is like a placeholder that tells the TypeScript compiler to ignore type checking for the particular variable, function, etc.

    Can represent any value

    A variable declared with any type can hold value of any datatype

    let x:any;
    x ="Hello";
    x =23;
    x =true;

    Here the variable x is declared with any type. This allows us to assign any value, string, number, boolean, etc. to the variable.

    The type of a variable of any type is undefined when you check using typeof operator

    let x:any;console.log(typeof x)// undefined

    On compiling, it will generate the following JavaScript code

    let x;
    console.log(typeof x);// undefined

    The output of the above example code is as follows

    undefined
    

    Example

    Let’s understand the any type with help of the below TypeScript example

    let x:any;console.log(typeof x);
    x ="Hello";console.log(typeof x);
    x =23;console.log(typeof x);
    x =true;console.log(typeof x);

    Here the variable is declared of any type. Then assigned this with values of different types (string, number and boolean).

    On compiling, it will generate the following JavaScript code

    let x;
    console.log(typeof x);
    x ="Hello";
    console.log(typeof x);
    x =23;
    console.log(typeof x);
    x =true;
    console.log(typeof x);

    The output of the above example code is as follows

    undefined 
    string 
    number 
    boolean
    

    Function Parameters of any Type

    You can also define a function with parameter of any type

    functionfunc(para:any){}

    Here the function func can take parameter of any type number, string, boolean, etc.

    Example

    Let’s take an example,

    functiongreet(name:any):string{returnHello Mr. ${name};}console.log(greet('Shahid'));console.log(greet(123));

    The function greet() is defined with a parameter of any type. So it can accept an argument of any type (number, string, etc.).

    We have called the greet() function passing two different values of string and number types. You can notice that it works for both types of the arguments.

    On compiling, the above typescript code will generate the following JavaScript code

    functiongreet(name){returnHello Mr. ${name};}
    console.log(greet('Shahid'));
    console.log(greet(123));

    The output of the above example code is as follows

    Hello Mr. Shahid 
    Hello Mr. 123
    

    Object of any Type

    An object can also be defined of any type. Such object can have the properties of any type. Lets take an example

    const student:any={
       name:"John Doe",
       age:32,
       isEnrolled:true,}

    Here the student object declared with any. It consists of three properties of different types.

    Example

    Try the following example,

    const student:any={
       name:"John Doe",
       age:32,
       isEnrolled:true,}console.log(student.name);console.log(student.age);console.log(student.isEnrolled);

    On compiling, it will generate the following JavaScript code

    const student ={
    
    name:"John Doe",
    age:32,
    isEnrolled:true,};
    console.log(student.name); console.log(student.age); console.log(student.isEnrolled);

    The output of the above example code is as follows

    John Doe
    32 
    true
    

    Why to use any Type?

    One reason to use any type is when you are working with the code that are not type-checked. For example, if you are using preexisting JavaScript code, the any type is useful in converting the JavaScript code to TypeScript. If you are using a third party library that is not written in TypeScript, you may need to use any type for the variable in TypeScript code.

    Another reason to use the any type is when you are not sure what will be the type of a value. For example, a function accepting user input can be defined with any type to handle any type of data from users.

    Any type is discouraged to use in new TypeScript code. It is advised to be careful when using the any type. If you use any type too often, you code will become less type safe.

    Type Assertion

    Use type assertion to narrow down the type of any variable

    let value:any="hello world";let lenStr:number=(value asstring).length;console.log(lenStr);

    In the above code, variable value is defined of any type. Then it is narrowed down to string.

    On compiling, it will generate the following JavaScript code

    let value ="hello world";let lenStr = value.length;
    console.log(lenStr);

    The output of the above code is as follows

    11
    

    Caution

    Any type can lead to error if not used with caution.

    In the below example, we are trying to access the property enrYear that doesn’t exist. This will cause a runtime error because we have defined student object with any. Notice it doesn’t show a compile time error.

    const student:any={
       name:"John Doe",
       age:32,
       isEnrolled:true,}console.log(student.name);console.log(student.age);console.log(student.enrYear);

    On compilation, it will generate the following JavaScript code

    const student ={
    
    name:"John Doe",
    age:32,
    isEnrolled:true,};
    console.log(student.name); console.log(student.age); console.log(student.enrYear);

    The output of the above example code is as follows

    John Doe 
    32 
    undefined
    

    Any vs. unknown

    When a variable is declared with any type and you can access its non-existing property.

    Example: Variable declared with any

    let user:any;
    user.isEnrolled;

    The above TypeScript code will not show any error at compilation. But it will through the following run time error.

    Cannot read properties of undefined (reading 'isEnrolled')
    

    Example: Variable declared with unknown

    let user:unknown;
    user.isEnrolled;

    The above code will show a compile time error as follows

    'user' is of type 'unknown'.
    
  • Enums

    Enums in TypeScript allow you to define a set of named constants. An enum is a way of giving more friendly names to sets of numeric values.

    Each enum member has a value associated with it. The value can be either constant or computed. The member value can be a numeric or string value.

    The Enum type in TypeScript is a user-defined data type. TypeScript has some features that are not the type-level extension of the JavaScript. Enum is one of the such few features along with type guards or union.

    enum enumName {// Enum members}

    The enums in TypeScript can be categorized in the following three types

    • Numeric enums
    • String enums
    • Heterogeneous enums

    Numeric Enums

    In this type of enum, members of an enum are assigned numeric values. Numeric enums possess an auto-increment nature. For instance, if we assign the number 5 to the first constant variable of the enum, then the following constant variables assign with values incremented by one, like 6 to the second member of the enum, 7 to the next, and so on.

    Example 1: Default numeric enums

    By default, enums in TypeScript are numeric. The first member is assigned a value of 0, and subsequent members are incremented by 1.

    enum Weekday {
      Monday,
      Tuesday,
      Wednesday,
      Thursday,
      Friday,}console.log(Weekday.Monday);console.log(Weekday.Tuesday);console.log(Weekday.Wednesday);console.log(Weekday.Thursday);console.log(Weekday.Friday);

    On compiling, it will generate the following JavaScript code

    var Weekday;(function(Weekday){
    
    Weekday&#91;Weekday&#91;"Monday"]=0]="Monday";
    Weekday&#91;Weekday&#91;"Tuesday"]=1]="Tuesday";
    Weekday&#91;Weekday&#91;"Wednesday"]=2]="Wednesday";
    Weekday&#91;Weekday&#91;"Thursday"]=3]="Thursday";
    Weekday&#91;Weekday&#91;"Friday"]=4]="Friday";})(Weekday ||(Weekday ={}));
    console.log(Weekday.Monday); console.log(Weekday.Tuesday); console.log(Weekday.Wednesday); console.log(Weekday.Thursday); console.log(Weekday.Friday);

    The output of the above example code is as follows

    0
    1
    2
    3
    4
    

    Notice that the first member is initialized with 0 and the subsequent members are incremented by the 1.

    Example 2: Initiated numeric enums

    In the below example, we have created an enum type named Color. Inside Color, three const variables are created with names Red, Yellow, and Green. We have initialized the first member and left other members for auto increment.

    enum Color{
      Red =10,
      Yellow,
      Green,}//print const variables valuesconsole.log(Color.Red);console.log(Color.Yellow);console.log(Color.Green);

    On compiling, it will generate the following JavaScript code

    var Color;(function(Color){
    
    Color&#91;Color&#91;"Red"]=10]="Red";
    Color&#91;Color&#91;"Yellow"]=11]="Yellow";
    Color&#91;Color&#91;"Green"]=12]="Green";})(Color ||(Color ={}));//print const variables values
    console.log(Color.Red); console.log(Color.Yellow); console.log(Color.Green);

    The output of the above example code is as follows

    10
    11
    12
    

    Example 3: Fully initialized numeric enums

    We can also set the values of all members of an enum. In the example below, we have initialized all member of the enum HttpStatus.

    enum HttpStatus {
      Success =200,
      NotFound =404,
      InternalServerError =500,}console.log(HttpStatus.Success);console.log(HttpStatus.NotFound);console.log(HttpStatus.InternalServerError);

    On compiling, it will generate the following JavaScript code

    var HttpStatus;(function(HttpStatus){
    
    HttpStatus&#91;HttpStatus&#91;"Success"]=200]="Success";
    HttpStatus&#91;HttpStatus&#91;"NotFound"]=404]="NotFound";
    HttpStatus&#91;HttpStatus&#91;"InternalServerError"]=500]="InternalServerError";})(HttpStatus ||(HttpStatus ={}));
    console.log(HttpStatus.Success); console.log(HttpStatus.NotFound); console.log(HttpStatus.InternalServerError);

    The output of the above example code is as follows

    200
    404
    500
    

    String Enums

    String enums are similar to numeric ones except that values of enums members are assigned with strings instead of numeric ones. The string enums do not possess auto-increment behavior.

    Example

    The following example creates an enum TrafficLight with three members. The members are initialized with string literals.

    enum TrafficLight {
      Red ="stop",
      Yellow ="caution",
      Green ="go",}console.log(TrafficLight.Red);console.log(TrafficLight.Yellow);console.log(TrafficLight.Green);

    On compiling, it will generate the following JavaScript code

    var TrafficLight;(function(TrafficLight){
    
    TrafficLight&#91;"Red"]="stop";
    TrafficLight&#91;"Yellow"]="caution";
    TrafficLight&#91;"Green"]="go";})(TrafficLight ||(TrafficLight ={}));
    console.log(TrafficLight.Red); console.log(TrafficLight.Yellow); console.log(TrafficLight.Green);

    The output of the above example code is as follows

    stop
    caution
    go
    

    Heterogeneous Enums

    This is a combination of both numeric and string enums. That is, in this type of enum, we can assign both string values or numeric values to its members.

    Example

    In the below example, we have created an enum type of Student. Inside the student are three const variables: Name, Gender, and Mobile. Name and Gender are of literal string types, whereas Mobile is of numeric value.

    enum student{
      Name ="srujana",
      Gender ="female",
      Mobile =901234567,}console.log(student.Name);console.log(student.Gender);console.log(student.Mobile);

    On compiling, it will generate the following JavaScript code

    var student;(function(student){
    
    student&#91;"Name"]="Srujana";
    student&#91;"Gender"]="Female";
    student&#91;student&#91;"Mobile"]=901234567]="Mobile";})(student ||(student ={}));
    console.log(student.Name); console.log(student.Gender); console.log(student.Mobile);

    The output of the above example code is as follows

    Srujana
    Female
    901234567
    

    Enums at runtime

    The enums are real objects that exist at run time. In the below example, the enum E is passed as parameter object to a function. It works, since ‘E’ has a property named ‘y’ which is a number.

    enum En {
      x,
      y,
      z,}functionfunc(obj:{ y:number}){return obj.y;}console.log(func(En));console.log(typeof En);

    On compiling, it will generate the following JavaScript code.

    var En;(function(En){
    
    En&#91;En&#91;"x"]=0]="x";
    En&#91;En&#91;"y"]=1]="y";
    En&#91;En&#91;"z"]=2]="z";})(En ||(En ={}));functionfunc(obj){return obj.y;}
    console.log(func(En)); console.log(typeof En);

    The output of the above code is as follows

    1
    object
    

    Enums at compile time

    When TypeScript enums are compiled, they are converted to JavaScript objects. The object will have a property for each enum member, and the value of each property will be the enum member’s value.

    The numeric and string enum members behave differently at the compilation. The numeric members are mapped bi-directionally to its corresponding JavaScript object property while string members are mapped uni-directionally to its runtime object property.

    enum Enum {
      Name ='John Doe',
      Age =32,}

    The above TypeScript code will be compiled to the following JavaScript code

    var Enum;(function(Enum){
    
    Enum&#91;"Name"]="John Doe";
    Enum&#91;Enum&#91;"Age"]=32]="Age";})(Enum ||(Enum ={}));</code></pre>

    Please note that the after compilation, the Name member get mapped unidirectionally and Age member get mapped bi-directionally to its corresponding runtime object properties.

    Const Enums

    The const enums are special enums in TypeScript that are completely removed during the compilation. These emums are not included in the compiled JavaScript output.

    Reverse Mapping

    As discussed above that the numeric enum members after compilation get mapped bidirectionally with its runtime object property. This is known as reverse mapping.

    enum Enum {A=1,}console.log(Enum.A)console.log(Enum['A'])console.log(Enum[1]);

    On compiling, it will generate the following JavaScript code.

    var Enum;(function(Enum){
    
    Enum&#91;Enum&#91;"A"]=1]="A";})(Enum ||(Enum ={}));
    console.log(Enum.A); console.log(Enum['A']); console.log(Enum[1]);

    The output of the above code is as follows

    1
    1
    A
    

    Ambient enums

    In TypeScript, ambient enums are used to describe the shape of the already existing enum types. The ambient enums don't generate any JavaScript code. To declare an ambient enum, you can use the declare keyword. Look at the below example

    declareenum Fruit {
    
    Apple,
    Orange,
    Banana,}</code></pre>

    The above code declares the shape of the enum without generating the JavaScript code. It means you can use the Fruit enum in TypeScript code but will not be included in compiled JavaScript code.

    Object vs. Enums

    An object with as const could suffice the need of the enums. So in modern TypeScript, you may not need enums. When an object could work as enums why to use a different type and also the objects align the state of the JavaScript.

    Let's look at the examples of enums and object with as const.

    // enumenum EWeekend {  
      Saturday,  
      Sunday,}console.log(EWeekend.Saturday)// object with as constconst OWeekend ={
    
    Saturday:0,
    Sunday:1,}asconst;console.log(OWeekend.Saturday);</code></pre>

    On compiling, it will generate the following JavaScript code

    // enumvar EWeekend;(function(EWeekend){
    
    EWeekend&#91;EWeekend&#91;"Saturday"]=0]="Saturday";
    EWeekend&#91;EWeekend&#91;"Sunday"]=1]="Sunday";})(EWeekend ||(EWeekend ={}));
    console.log(EWeekend.Saturday);// object with as constconst OWeekend ={
    Saturday:0,
    Sunday:1,};
    console.log(OWeekend.Saturday);

    The output of the above example code is as follows

    0
    0
    

    Using enum as a function parameter

    We can use the enum as a parameter in the function definition.

    enum Color {
      Red,
      Green,
      Blue,}functionprintColor(color: Color):void{console.log(color);}printColor(Color.Red);// Prints 0 to the console

    In the above example, the function printColor() takes a parameter of type Color. It returns nothing but logs the color in the console.

    On compiling, it will generate the following JavaScript code

    var Color;(function(Color){
    
    Color&#91;Color&#91;"Red"]=0]="Red";
    Color&#91;Color&#91;"Green"]=1]="Green";
    Color&#91;Color&#91;"Blue"]=2]="Blue";})(Color ||(Color ={}));functionprintColor(color){
    console.log(color);}printColor(Color.Red);// Prints 0 to the console</code></pre>

    The above example code will produce the following output

    0
    
  • Tuples

    At times, there might be a need to store a collection of values of varied types. Arrays will not serve this purpose. TypeScript gives us a data type called tuple that helps to achieve such a purpose.

    It represents a heterogeneous collection of values. In other words, tuples enable storing multiple fields of different types. Tuples can also be passed as parameters to functions.

    Syntax

    We can create a tuple using JavaScripts array syntax:

    const tupleName =[value1, value2, value3,...valueN]

    But we need to declare its type as a tuple.

    const tupleName:[type1, type2, type3,...typeN]=[value1, value2, value3,...valueN]

    For Example

    const myTuple:[number,string]=[10,"Hello"];

    You can define a tuple first and then initialize,

    let myTuple:[number,string];// declaring the tuple
    myTuple =[10,"Hello"];// initializing the tuple

    Make sure, the const tuple declared must be initialized.

    You can also declare an empty tuple in Typescript and choose to initialize it later.

    var myTuple =[]; 
    myTuple[0]=10;
    myTuple[1]="Hello";

    Accessing Values in Tuples

    Tuple values are individually called items. Tuples are index based. This means that items in a tuple can be accessed using their corresponding numeric index. Tuple items index starts from zero and extends up to n-1(where n is the tuples size).

    Syntax

    Following is the syntax to access the values in a tuple using its index −

    tupleName[index]

    Example: Simple Tuple

    var myTuple:[number,string]=[10,"Hello"];//create a tuple console.log(myTuple[0])console.log(myTuple[1])

    In the above example, a tuple, myTuple, is declared. The tuple contains values of numeric and string types respectively.

    On compiling, it will generate the following code in JavaScript.

    var myTuple =[10,"Hello"];//create a tuple 
    console.log(myTuple[0]);
    console.log(myTuple[1]);

    Its output is as follows −

    10 
    Hello
    

    Example: Empty Tuple

    We can declare an empty tuple as follows and then initialize it.

    var tup =[] 
    tup[0]=12 
    tup[1]=23console.log(tup[0])console.log(tup[1])

    On compiling, it will generate the same code in JavaScript.

    Its output is as follows −

    12 
    23 
    

    Tuple Operations

    Tuples in TypeScript supports various operations like pushing a new item, removing an item from the tuple, etc.

    Example

    var myTuple:[number,string,string,string]; 
    myTuple =[10,"Hello","World","typeScript"];console.log("Items before push "+ myTuple.length)
    
    myTuple.push(12)// append value to the tuple console.log("Items after push "+ myTuple.length)console.log("Items before pop "+ myTuple.length)// removes and returns the last itemconsole.log(myTuple.pop()+" popped from the tuple")console.log("Items after pop "+ myTuple.length)
    • The push() appends an item to the tuple
    • The pop() removes and returns the last value in the tuple

    On compiling, it will generate the following code in JavaScript.

    var myTuple;
    myTuple =[10,"Hello","World","typeScript"];
    console.log("Items before push "+ myTuple.length);
    myTuple.push(12);// append value to the tuple 
    console.log("Items after push "+ myTuple.length);
    console.log("Items before pop "+ myTuple.length);// removes and returns the last item
    console.log(myTuple.pop()+" popped from the tuple"); 
    console.log("Items after pop "+ myTuple.length);

    The output of the above code is as follows −

    Items before push 4 
    Items after push 5 
    Items before pop 5 
    12 popped from the tuple 
    Items after pop 4
    

    Updating Tuples

    Tuples are mutable which means you can update or change the values of tuple elements.

    Example

    var myTuple:[number,string,string,string];// define tuple
    myTuple =[10,"Hello","World","typeScript"];// initialize tupleconsole.log("Tuple value at index 0 "+ myTuple[0])//update a tuple element 
    myTuple[0]=121console.log("Tuple value at index 0 changed to   "+ myTuple[0])

    On compiling, it will generate the following code in JavaScript.

    var myTuple;// define tuple
    myTuple =[10,"Hello","World","typeScript"];// initialize tuple
    console.log("Tuple value at index 0 "+ myTuple[0]);//update a tuple element 
    myTuple[0]=121;
    console.log("Tuple value at index 0 changed to   "+ myTuple[0]);

    The output of the above code is as follows −

    Tuple value at index 0 10 
    Tuple value at index 0 changed to 121
    

    Destructuring a Tuple

    Destructuring refers to breaking up the structure of an entity. TypeScript supports destructuring when used in the context of a tuple.

    Example

    var a:[number,string]=[10,"hello"];var[b, c]= a;console.log( b );console.log( c );

    On compiling, it will generate following JavaScript code.

    var a =[10,"hello"];var b = a[0], c = a[1];
    console.log(b);
    console.log(c);

    Its output is as follows −

    10
    hello 
    

    Function Parameters and Tuple Types

    We can define a function to accept explicitly a tuple type. So while calling the function we pass the tuple as argument.

    Example

    functionprocessData(data:[string,number]):void{const[name, age]= data;console.log(Name: ${name}, Age: ${age});}let data:[string,number]=["John",32]processData(data);

    We defined here a function processData() that accepts a parameter of tuple type. Inside the function we use tuple destructuring to get the constituent elements. We call the function passing a tuple as argument.

    On compiling, it will generate the following JavaScript code.

    functionprocessData(data){const[name, age]= data;
    
    console.log(Name: ${name}, Age: ${age});}let data =&#91;"John",32];processData(data);</code></pre>

    The output of the above code is as follows −

    Name: John, Age: 32
    
  • Arrays

    The use of variables to store values poses the following limitations −

    • Variables are scalar in nature. In other words, a variable declaration can only contain a single at a time. This means that to store n values in a program n variable declarations will be needed. Hence, the use of variables is not feasible when one needs to store a larger collection of values.
    • Variables in a program are allocated memory in random order, thereby making it difficult to retrieve/read the values in the order of their declaration.

    TypeScript introduces the concept of arrays to tackle the same. An array is a homogenous collection of values. To simplify, an array is a collection of values of the same data type. It is a user defined type.

    Features of an Array

    Here is a list of the features of an array −

    • An array declaration allocates sequential memory blocks.
    • Arrays are static. This means that an array once initialized cannot be resized.
    • Each memory block represents an array element.
    • Array elements are identified by a unique integer called as the subscript / index of the element.
    • Like variables, arrays too, should be declared before they are used. Use the var keyword to declare an array.
    • Array initialization refers to populating the array elements.
    • Array element values can be updated or modified but cannot be deleted.

    Declaring and Initializing Arrays

    To declare an initialize an array in Typescript use the following syntax −

    Syntax

    var array_name[:datatype];        //declaration 
    array_name = [val1,val2,valn..]   //initialization
    

    An array declaration without the data type is deemed to be of the type any. The type of such an array is inferred from the data type of the arrays first element during initialization.

    For example, a declaration like − var numlist:number[] = [2,4,6,8] will create an array as given below −

    Declaring and Initializing Arrays

    The array pointer refers to the first element by default.

    Arrays may be declared and initialized in a single statement. The syntax for the same is −

    var array_name[:data type] = [val1,val2valn]
    

    Note − The pair of [] is called the dimension of the array.

    Accessing Array Elements

    The array name followed by the subscript is used refer to an array element. Its syntax is as follows −

    array_name[subscript] = value
    

    Example: Simple Array

    var alphas:string[]; 
    alphas =["1","2","3","4"]console.log(alphas[0]);console.log(alphas[1]);

    On compiling, it will generate following JavaScript code −

    var alphas;
    alphas =["1","2","3","4"];console.log(alphas[0]);console.log(alphas[1]);

    The output of the above code is as follows −

    1 
    2 
    

    Example: Single statement declaration and initialization

    var nums:number[]=[1,2,3,3]console.log(nums[0]);console.log(nums[1]);console.log(nums[2]);console.log(nums[3]);

    On compiling, it will generate following JavaScript code −

    var nums =[1,2,3,3];console.log(nums[0]);console.log(nums[1]);console.log(nums[2]);console.log(nums[3]);

    Its output is as follows −

    1 
    2 
    3 
    3 
    

    Array Object

    An array can also be created using the Array object. The Array constructor can be passed.

    • A numeric value that represents the size of the array or
    • A list of comma separated values.

    The following example shows how to create an array using this method.

    Example

    var arr_names:number[]=newArray(4)for(var i =0;i<arr_names.length;i++){ 
       arr_names[i]= i *2console.log(arr_names[i])}

    On compiling, it will generate following JavaScript code.

    var arr_names =newArray(4);for(var i =0; i < arr_names.length; i++){
       arr_names[i]= i *2;console.log(arr_names[i]);}

    Its output is as follows −

    0 
    2 
    4 
    6 
    

    Example: Array Constructor accepts comma separated values

    var names:string[]=newArray("Mary","Tom","Jack","Jill")for(var i =0;i<names.length;i++){console.log(names[i])}

    On compiling, it will generate following JavaScript code −

    var names =newArray("Mary","Tom","Jack","Jill");for(var i =0; i < names.length; i++){console.log(names[i]);}

    Its output is as follows −

    Mary 
    Tom 
    Jack 
    Jill
    

    Array Methods

    A list of the methods of the Array object along with their description is given below.

    S.No.Method & Description
    1.concat()Returns a new array comprised of this array joined with other array(s) and/or value(s).
    2.every()Returns true if every element in this array satisfies the provided testing function.
    3.filter()Creates a new array with all of the elements of this array for which the provided filtering function returns true.
    4.forEach()Calls a function for each element in the array.
    5.indexOf()Returns the first (least) index of an element within the array equal to the specified value, or -1 if none is found.
    6.join()Joins all elements of an array into a string.
    7.lastIndexOf()Returns the last (greatest) index of an element within the array equal to the specified value, or -1 if none is found.
    8.map()Creates a new array with the results of calling a provided function on every element in this array.
    9.pop()Removes the last element from an array and returns that element.
    10.push()Adds one or more elements to the end of an array and returns the new length of the array.
    11.reduce()Apply a function simultaneously against two values of the array (from left-to-right) as to reduce it to a single value.
    12.reduceRight()Apply a function simultaneously against two values of the array (from right-to-left) as to reduce it to a single value.
    13.reverse()Reverses the order of the elements of an array — the first becomes the last, and the last becomes the first.
    14.shift()Removes the first element from an array and returns that element.
    15.slice()Extracts a section of an array and returns a new array.
    16.some()Returns true if at least one element in this array satisfies the provided testing function.
    17.sort()Sorts the elements of an array.
    18.splice()Adds and/or removes elements from an array.
    19.toString()Returns a string representing the array and its elements.
    20.unshift()Adds one or more elements to the front of an array and returns the new length of the array.

    Array Destructuring

    Refers to breaking up the structure of an entity. TypeScript supports destructuring when used in the context of an array.

    Example

    var arr:number[]=[12,13]var[x,y]= arr 
    console.log(x)console.log(y)

    On compiling, it will generate following JavaScript code.

    var arr =[12,13];var x = arr[0], y = arr[1];console.log(x);console.log(y);

    Its output is as follows −

    12 
    13
    

    Array Traversal using forin loop

    One can use the forin loop to traverse through an array.

    var j:any;var nums:number[]=[1001,1002,1003,1004]for(j in nums){console.log(nums[j])}

    The loop performs an index based array traversal.

    On compiling, it will generate following JavaScript code.

    var j;var nums =[1001,1002,1003,1004];for(j in nums){console.log(nums[j]);}

    The output of the above code is given below −

    1001 
    1002 
    1003 
    1004
    

    Arrays in TypeScript

    TypeScript supports the following concepts in arrays −

    S.No.Concept & Description
    1.Multi-dimensional arraysTypeScript supports multidimensional arrays. The simplest form of the multidimensional array is the twodimensional array.
    2.Passing arrays to functionsYou can pass to the function a pointer to an array by specifying the array’s name without an index.
    3.Return array from functionsAllows a function to return an array
  • Boolean

    The TypeScript Boolean types represent logical values like true or false. Logical values are used to control the flow of the execution within the program. As JavaScript offers both Boolean primitive and object types, TypeScript adds a type annotation. We can create a boolean primitive as well boolean object.

    We can create a boolean object by using the Boolean() constructor with new keyword.

    To convert a non-boolean value to boolean we should use Boolean() function or double NOT (!!) operator. We should not use Boolean constructor with new keyword.

    Syntax

    To declare a boolean value (primitive) in TypeScript we can use keyword “boolean”.

    let varName:boolean=true;

    In the above syntax, we declare a boolean variable varName and assign the value true.

    To create a Boolean object we use the Boolean() constructor with new Keyword.

    const varName =newBoolean(value);

    In the above syntax, the value is an expression to be converted to Boolean object. The Boolean() constructor with new returns an object containing the boolean value.

    For example,

    const isTrue =newBoolean(true);

    In the above example, isTrue holds value true while isFalse holds the value false.

    Type Annotations

    The type annotations in TypeScript is optional as TypeScript can infer the types of the variable automatically. We can use the boolean keyword to annotate the types of boolean variables.

    let isPresent :boolean=true;// with type annotationlet isPresent =true// without type annotation

    Like variables, the function parameters and return type can also be annotated.

    Truthy and Falsy Values

    In TypeScript, falsy values are the values that are evaluated to false. There are six falsy values

    • false
    • 0 (zero)
    • Empty string (“”)
    • null
    • undefined
    • NaN

    The all other values are truthy.

    Converting a non-boolean value to boolean

    All the above discussed falsy values are converted to false and truthy values are converted to true. To convert a non-boolean value to boolean, we can use the Boolean() function and double NOT (!!) operator.

    Using the Boolean() Function

    The Boolean() function in TypeScript converts a non-boolean value to boolean. It returns a primitive boolean value.

    let varName =Boolean(value);

    The value is an expression to be converted to boolean.

    Example

    In the below example, we use the Boolean() function to convert a non-boolean value to boolean.

    const myBoolean1 =Boolean(10);console.log(myBoolean1);// trueconst myBoolean2 =Boolean("");console.log(myBoolean2);// false

    On compiling, the above code will produce the same code in JavaScript. On executing the JavaScript code will produce the following output

    true
    false
    

    Using Double NOT (!!) Operator

    The double NOT (!!)operator in TypeScript converts a non-boolean value to boolean. It returns a primitive boolean value.

    let varName =!!(value);

    The value is an expression to be converted to boolean.

    Example

    In the below example, we use the double NOT (!!) operator to convert a non-boolean value to boolean.

    const myBoolean1 =!!(10);console.log(myBoolean1);// trueconst myBoolean2 =!!("");console.log(myBoolean2);// false

    On compiling, the above code will produce the same code in JavaScript. On executing the JavaScript code will produce the following output

    true
    false
    

    Boolean Operations

    The boolean operations or logical operations in TypeScript can be performed using the three logical operators, logical AND, OR and NOT operators. These operations return a boolean value (true or false).

    Example: Logical AND (&&)

    In the example below, we defined two boolean variables x and y. Then perform the logical AND (&&) of these variables.

    let x:boolean=true;let y:boolean=false;let result:boolean= x && y;console.log(result);// Output: false

    On compiling, it will generate the following JavaScript code.

    var x =true;var y =false;var result = x && y;console.log(result);// Output: false

    The output of the above example code is as follows

    false
    

    Example: Logical OR (||)

    In the example below, we perform logical OR (||) operation of the two boolean variables x and y.

    let x:boolean=true;let y:boolean=false;let result:boolean= x || y;console.log(result);// Output: true

    On compiling, it will generate the following JavaScript code.

    var x =true;var y =false;var result = x || y;console.log(result);// Output: true

    The output of the above example code is as follows

    true
    

    Example: Logical NOT (!)

    The logical NOT (!) operation of the boolean variable isPresent is performed in the below example.

    let isPresent:boolean=false;let isAbsent:boolean=!isPresent;console.log(isAbsent);// Output: true

    On compiling, it will generate the same code in JavaScript.

    The output of the above example code is as follows

    true
    

    Conditional Expression with Booleans

    Example: If statement

    The below example shows how to use the conditional expression with boolean in if else statement.

    let age:number=25;let isAdult:boolean= age >=18;if(isAdult){console.log('You are an adult.');}else{console.log('You are not an adult.');}

    On compiling it will generate the following JavaScript code

    let age =25;let isAdult = age >=18;if(isAdult){
    
    console.log('You are an adult.');}else{
    console.log('You are not an adult.');}</code></pre>

    The output of the above example code is as follows

    You are an adult.
    

    Example: Conditional Statement (Ternary Operator)

    Try the following example

    let score:number=80;let isPassing:boolean= score >=70;let result:string= isPassing ?'Pass':'Fail';console.log(result);// Output: Pass

    On compiling, it will generate the following JavaScript code

    let score =80;let isPassing = score >=70;let result = isPassing ?'Pass':'Fail';
    console.log(result);// Output: Pass

    The output of the above example code is as follows

    Pass
    

    TypeScript Boolean vs boolean

    The Boolean is not same as the boolean type. The Boolean does not refer to the primitive value. Whereas the boolean is primitive data type in TypeScript. You should always use the boolean with lowercase.

    Boolean Objects

    As we have seen above, we can create a Boolean object consisting boolean value using the Boolean constructor with new keyword. The Boolean wrapper class provides us with different properties and methods to work with boolean values.

    Boolean Properties

    Here is a list of the properties of Boolean object

    Sr.No.Property & Description
    1constructorReturns a reference to the Boolean function that created the object.
    2prototypeThe prototype property allows you to add properties and methods to an object.

    In the following sections, we will have a few examples to illustrate the properties of Boolean object.

    Boolean Methods

    Here is a list of the methods of Boolean object and their description.

    Sr.No.Method & Description
    1toSource()Returns a string containing the source of the Boolean object; you can use this string to create an equivalent object.
    2toString()Returns a string of either "true" or "false" depending upon the value of the object.
    3valueOf()Returns the primitive value of the Boolean object.

    In the following sections, we will have a few examples to demonstrate the usage of the Boolean methods.

  • Strings

    In TypeScript, a string represents a sequence of characters. The string type is a fundamental data type in TypeScript. Strings are important to hold data that can be represented in text form. Like JavaScript, TypeScript also supports both string primitives and String objects.

    The String object lets you work with a series of characters. It wraps the string primitive data type with a number of helper methods.

    You can invoke methods on primitive strings because TypeScript automatically wraps the string primitive and call the methods on wrapper object. The same applies to properties also.

    Creating Strings

    Strings in TypeScript can be created as primitives from string literals or as objects using the String() constructor.

    You can use the following syntax to create a String object in TypeScript −

    cost str =newString(value);

    Here str is the newly created String object and value is a series of characters.

    You can create string primitives using single quote, double quotes and backtick.

    let str1:string='a string primitive';let str2:string="another string";let str3:string=yet another string;

    The string primitives can also be created using the String() function without new keyword.

    let str:string=String(value);

    ‘string’ is a primitive, but ‘String’ is a wrapper object. Prefer using ‘string’ when possible.

    String Properties

    A list of the methods available in String object along with their description is given below −

    S.No.Property & Description
    1.ConstructorReturns a reference to the String function that created the object.
    2.LengthReturns the length of the string.
    3.PrototypeThe prototype property allows you to add properties and methods to an object.

    String Methods

    A list of the methods available in String object along with their description is given below −

    S.No.Method & Description
    1.charAt()Returns the character at the specified index.
    2.charCodeAt()Returns a number indicating the Unicode value of the character at the given index.
    3.concat()Combines the text of two strings and returns a new string.
    4.indexOf()Returns the index within the calling String object of the first occurrence of the specified value, or -1 if not found.
    5.lastIndexOf()Returns the index within the calling String object of the last occurrence of the specified value, or -1 if not found.
    6.localeCompare()Returns a number indicating whether a reference string comes before or after or is the same as the given string in sort order.
    7.match()Used to match a regular expression against a string.
    8.replace()Used to find a match between a regular expression and a string, and to replace the matched substring with a new substring.
    9.search()Executes the search for a match between a regular expression and a specified string.
    10.slice()Extracts a section of a string and returns a new string.
    11.split()Splits a String object into an array of strings by separating the string into substrings.
    12.substr()Returns the characters in a string beginning at the specified location through the specified number of characters.
    13.substring()Returns the characters in a string between two indexes into the string.
    14.toLocaleLowerCase()The characters within a string are converted to lower case while respecting the current locale.
    15.toLocaleUpperCase()The characters within a string are converted to upper case while respecting the current locale.
    16.toLowerCase()Returns the calling string value converted to lower case.
    17.toString()Returns a string representing the specified object.
    18.toUpperCase()Returns the calling string value converted to uppercase.
    19.valueOf()Returns the primitive value of the specified object.

    Examples

    Lets understand the string types with the help of some examples in TypeScript.

    Example: Creating String Primitives

    In the example below, we use single quote, double quote and backtick to create the primitive strings str1, str2 and str3 respectively.

    let str1:string='a string primitive';console.log(str1);let str2:string="another string";console.log(str2);let str3:string=yet another string;console.log(str3);

    On compiling, it will generate the following JavaScript code.

    let str1 ='a string primitive';
    console.log(str1);let str2 ="another string";
    console.log(str2);let str3 =yet another string;
    console.log(str3);

    The output of the above example code is as follows −

    a string primitive
    another string
    yet another string
    

    Example: Creating String Objects

    Here we create a String object using the String() constructor with new keyword.

    const email =newString('[email protected]');console.log(email);console.log(typeof email);

    On compiling, it will generate the following JavaScript code.

    const email =newString('[email protected]');
    console.log(email);
    console.log(typeof email);

    The output of the above example code is as follows −

    [email protected]
    object
    

    Example: Concatenating TypeScript strings

    To concatenate two string, we can use + operator. Here, we concatenate two strings str1 and str2 and display the result in the console.

    let str1:string="Hello ";let str2:string="World!";let str3:string= str1 + str2;console.log(str3);

    On compiling, it will generate the following JavaScript code.

    let str1 ="Hello ";let str2 ="World!";let str3 = str1 + str2;
    console.log(str3);

    The output of the above example code is as follows

    Hello World!
    

    Example: Accessing string elements using indexing

    In the example below, we access the string characters from the 1st and 6th indices.

    let message:string="Hello World!";console.log("Character at index 1 is => "+ message[1]);console.log("Character at index 6 is => "+ message[6]);

    On compiling, it will generate the following JavaScript code.

    let message ="Hello World!";
    console.log("Character at index 1 is => "+ message[1]);
    console.log("Character at index 6 is => "+ message[6]);

    The output of the above example code is as follows −

    Character at index 1 is => e
    Character at index 6 is => W
    

    Example: String vs. string in TypeScript

    In TypeScript, type ‘String’ is a wrapper object and type ‘string’ is a primitive type. These both types cant be assigned to each other.

    In the example below, we tried to assign a string object to a variable of type string primitive.

    let str:string;
    str =newString('shahid');

    The above example code will show the following error −

    Type 'String' is not assignable to type 'string'.
      'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.
    
  • Numbers

    TypeScript like JavaScript supports numeric values as Number objects. A number object converts numeric literal to an instance of the number class. The Number class acts as a wrapper and enables manipulation of numeric literals as they were objects.

    TypeScript number type represents the numeric values. All the numbers are represented as the floating point values. TypeScript also supports the binary, octal and hexadecimal numbers introduced in ECMAScript 2015.

    In TypeScript, we can create a number primitive as well as Number object.

    Syntax

    We can declare a variable of number type using colon (:) after the variable name followed by number −

    let varName:number= value;

    In the above syntax, we declared a variable named varName of number type. Here value is the any numeric value such as decimal, binary, octal or hexadecimal numbers.

    We can create the Number object. To create a Number object we can use the Number() constructor as follows −

    var var_name =newNumber(value)

    In case a non-numeric argument is passed as an argument to the Numbers constructor, it returns NaN (NotaNumber)

    The type ‘Number’ is a wrapper object but type ‘number’ is a primitive. Prefer using ‘number’ when possible. Type ‘Number’ is not assignable to type ‘number’.

    Creating Number Types

    In the below example, we created a variable count of number type. We assigned 10 to the count.

    let count:number=10;console.log(count);

    On compiling, it will generate the following JavaScript code.

    let count =10;
    console.log(count);

    The output is as follows −

    10
    

    We can also assign float, binary, octal and hexadecimal values to a variable of number type. Look at the below TypeScript code snippet

    let decNum:number=10.6;// floating point numberlet binNum:number=0b101001;// binary numberlet octNum:number=0o45;// octal numberlet hexNum:number=0x80fd;// hexadecimal number

    Creating Number Object

    const count =newNumber(10);
    console.log(count);
    console.log(typeof count);

    On compiling, it will generate the same JavaScript code.

    The output of the above example code is as follows

    [Number: 10]
    Object
    

    Number Properties

    The following table lists a set of properties of the Number object −

    S.No.Property & Description
    1.MAX_VALUEThe largest possible value a number in JavaScript can have 1.7976931348623157E&plus;308.
    2.MIN_VALUEThe smallest possible value a number in JavaScript can have 5E-324.
    3.NaNEqual to a value that is not a number.
    4.NEGATIVE_INFINITYA value that is less than MIN_VALUE.
    5.POSITIVE_INFINITYA value that is greater than MAX_VALUE.
    6.prototypeA static property of the Number object. Use the prototype property to assign new properties and methods to the Number object in the current document.
    7.constructorReturns the function that created this object’s instance. By default, this is the Number object.

    Example

    console.log("TypeScript Number Properties: ");console.log("Maximum value that a number variable can hold: "+ Number.MAX_VALUE);console.log("The least value that a number variable can hold: "+ Number.MIN_VALUE);console.log("Value of Negative Infinity: "+ Number.NEGATIVE_INFINITY);console.log("Value of Negative Infinity:"+ Number.POSITIVE_INFINITY);

    On compiling, it will generate the same code in JavaScript.

    Its output is as follows −

    TypeScript Number Properties:  
    Maximum value that a number variable can hold: 1.7976931348623157e+308 
    The least value that a number variable can hold: 5e-324 
    Value of Negative Infinity: -Infinity 
    Value of Negative Infinity:Infinity
    

    Example: NaN

    var month =0if( month<=0|| month >12){ 
       month = Number.NaNconsole.log("Month is "+ month)}else{console.log("Value Accepted..")}

    On compiling, it will generate the same code in JavaScript.

    Its output is as follows −

    Month is NaN
    

    Example: prototype

    functionemployee(id:number,name:string){this.id = id 
       this.name = name 
    }var emp =newemployee(123,"Smith") 
    employee.prototype.email ="[email protected]"console.log("Employee's Id: "+emp.id)console.log("Employee's name: "+emp.name)console.log("Employee's Email ID: "+emp.email)

    On compiling, it will generate the following JavaScript code −

    //Generated by typescript 1.8.10functionemployee(id, name){this.id = id;this.name = name;}var emp =newemployee(123,"Smith");
    employee.prototype.email ="[email protected]";
    
    console.log("Employee 's Id: "+ emp.id);
    console.log("Employee's name: "+ emp.name);
    console.log("Employee's Email ID: "+ emp.email);

    Its output is as follows −

    Employee's Id: 123 
    Emaployee's name: Smith 
    Employee's Email ID: [email protected]
    

    Number Methods

    The Number object contains only the default methods that are a part of every object’s definition. Some of the commonly used methods are listed below −

    S.No.Methods & Description
    1.toExponential()Forces a number to display in exponential notation, even if the number is in the range in which JavaScript normally uses standard notation.
    2.toFixed()Formats a number with a specific number of digits to the right of the decimal.
    3.toLocaleString()Returns a string value version of the current number in a format that may vary according to a browser’s local settings.
    4.toPrecision()Defines how many total digits (including digits to the left and right of the decimal) to display of a number. A negative precision will throw an error.
    5.toString()Returns the string representation of the number’s value. The function is passed the radix, an integer between 2 and 36 specifying the base to use for representing numeric values.
    6.valueOf()Returns the number’s primitive value.
  • Type Inference

    Type inference is a feature in TypeScript that allows the compiler to automatically determine (infer) the type of a variable, function or expression. TypeScript is an optionally static type programming language. You can declare variables, expressions, or functions without explicitly annotating their types. The compiler will automatically determine the types at the compile time.

    The type inference can be done on the basis of a number of factors, including

    • The type of values assigned to the variables.
    • The type of function parameters or arguments passed to the function.
    • The type of return value of the function.
    • The types of the object and properties.

    Let’s take a simple example as follows

    let x =5;let y ="Hello World!";

    In the above code, the TypeScript compiler can infer that the type of variable x is number. This is because the variable x is being assigned a number. The compiler can also infer the type of y is string because the y is being assigned a string.

    In the above example, TypeScript automatically infers the types of variables based on the values assigned to them.

    Variable or Member Initialization

    The type inference can be inferred using the variable and member initialization. The TypeScript compiler infers the type of the variable from the initialized value.

    Example

    Let’s take an example of variable initialization as follows

    let x =20;let y ="Hello World!";let z =true;console.log("type of x: ",typeof x);console.log("type of y: ",typeof y);console.log("type of z: ",typeof z);

    On compilation, it will generate the same JavaScript code.

    The output of the above example code is as follows

    type of x:  number
    type of y:  string
    type of z:  boolean
    

    Lets have an example of object member initialization

    classPerson{
      name ="Shahid";
      age =35;}const p =newPerson();// Prints name and ageconsole.log(${p.name}, ${p.age});

    On compilation, it will generate following JavaScript code.

    classPerson{constructor(){this.name ="Shahid";this.age =35;}}const p =newPerson();// Prints name and ageconsole.log(${p.name}, ${p.age});

    The output of the above code is as follows

    Shahid, 35
    

    Function Default Parameter

    The typescript compiler can also infer the type of the function parameters when the parameters are initialized with default values.

    In the below example, the parameters x and y are initialized with default values. The compiler infers the type of x and y as number. This is because the initialized values are numbers.

    functionadd(x =10, y =30){return x + y;}let res =add(2,3);console.log(res);

    On compilation, it will generate the same code in JavaScript.

    The output of the above example code is as follows

    5
    

    Now let’s try to pass arguments as string values.

    let res2 =add('2','3');

    The type of the parameters of the function add are inferred as number so when we pass arguments of type string to the function, it shows the following error

    Argument of type 'string' is not assignable to parameter of type 'number'.
    

    Function Return Type

    The TypeScript compiler infers the type of the return type of the function based on the type of the return value.

    If the function doesn’t return any value, then the return type is void.

    In the example below, the function add accepts the two numbers and return their sum. As the sum of two numbers are number, so the type of return value is number. Hence the compiler infers the return type of the function add as number.

    functionadd(x:number, y:number){return x + y;}let res1:number=add(2,3);console.log(res1);

    When we assign the return value of the function add to variable (res2) of type string, it will show an error.

    let res2:string=add(2,3);

    The error is as follows

    Type 'number' is not assignable to type 'string'.
    

    This is because the return type of the function add is number and we are assigning it to variable of string type.

    Best Common Type: The Union Type

    Type inference with variable initialization, function default parameters and return type is straightforward.

    When TypeScript infers a type from multiple expressions, the type of the expressions is determined as the “best common type”.

    Let’s understand this with the help of an example

    const a =[5,10,"TypeScript"];

    In the above example, the array contains values 5, 10, and “TypeScript”. To infer the type of the array, we must consider the type of each element. Here, we have choices for the type of the array as number, and string. The inferred type of the array should be the best common type for each value in the array.

    The best common type has to be chosen from the provided candidate type. If there is no super type of all candidate types, the union type is used. Hence the inferred type of the above array is

    (number | string)[]
    

    The above array can contain values of types number, and string only. If you try to add a value of type different from number and string, it will show an error.

    Let’s try to add a boolean value to the array.

    const a =[5,10,"TypeScript"];
    a.push(true);

    The above code will show the following compilation error

    Argument of type ‘boolean’ is not assignable to parameter of type ‘string | number’.

    Contextual Typing

    Contextual typing is a feature in TypeScript that allows the compiler to infer the type of variable, parameter or expression based on the context where they are used. For example,

    window.onmousedown=function(mouseEvent){console.log(mouseEvent.button);}

    In the above example, the TypeScript infers the type the function expression on right hand side of the assignment using the type of the Window.onmousedown function. So it is able to infer the type of mouseEvent parameter as MouseEvent. This way TypeScript infers that mouseEvent has a button property and doesn’t show a compilation error.

    Contextual typing is very helpful in writing concise code without losing type safety.