Author: saqibkhan

  • Indexed Access Types

    In TypeScript, Indexed access types are also known as lookup types. It is used to access the type of property of another type. It is a powerful way and helpful to access the type properties of the complex type structure. This feature allows you to use the type system more effectively, ensuring type safety in scenarios involving property access and manipulation.

    Syntax

    You can follow the syntax below to use the index access types in TypeScript.

    typenew_type= existing_type[key];
    • In the above syntax, ‘type’ is a keyword to define a new type.
    • ‘existing_type’ is an existing type.
    • The ‘key’ is a property of the existing_type whose type we need to get.

    Examples

    Let’s understand the indexed access types with the help of some examples in TypeScript.

    Example: Accessing Object Property Types

    Indexed access types are very useful when you need to get the type of the specific property of the existing type.

    In the code below, we have defined the User type which contains the id, and age properties of the number type and name property of the string type.

    The User[‘name’] is used to access the type of the ‘name’ property of the User type, which is a string.

    Next, we have defined the userName variable whose type is ‘UserNameType’ (string). If you try to assign a number to the userName variable, it will throw an error.

    typeUser={
    
    id:number;
    name:string;
    age:number;};// Access the type of 'name' property from UsertypeUserNameType= User['name'];// type is stringlet userName: UserNameType;
    userName ="Alice";// Okconsole.log(userName);// Alice// userName = 123; // Error: Type 'number' is not assignable to type 'string'.

    On compiling, it will generate the following JavaScript code.

    let userName;
    userName ="Alice";// Okconsole.log(userName);// Alice// userName = 123;   // Error: Type 'number' is not assignable to type 'string'.

    Output

    Alice
    

    Example: Accessing Nested Object Property Types

    Indexed access types are more useful when you need to get the type of any property of the complex type structure.

    In the code below, the ‘Product’ type has id and details properties. The details property is a nested type containing the name and price properties.

    We used the Product[‘details’][‘price’] to access the type of the ‘price’ property of the ‘details’ property, which is a number.

    typeProduct={
    
    id:number;
    details:{
        name:string;
        price:number;};};// Access the type of the nested 'price' propertytypeProductPriceType= Product['details']['price'];// type is numberlet price: ProductPriceType;
    price =19.99;// Correct usageconsole.log(price);// Output: 19.99// price = "20.00"; // Error: Type 'string' is not assignable to type 'number'.

    On compiling, it will generate the following JavaScript code.

    let price;
    price =19.99;// Correct usageconsole.log(price);// Output: 19.99// price = "20.00"; // Error: Type 'string' is not assignable to type 'number'.

    Output

    19.99
    

    Example: Using the keyof operator with indexed access types

    This example is similar to the first example. Here, we have used the ‘keyof’ operator to access all keys of the User type.

    When you use the Keyof operator with the type and use it as an index value, it gets the union of type of all properties of the object. Here, ‘keyof User’ gives us the number | string, which is a type of all properties of the User type.

    typeUser={
    
    id:number;
    name:string;
    age:number;};// Access the type of 'name' property from UsertypeUserNameType= User[keyof User];// type is number | stringlet userName: UserNameType;
    userName ="Hello";// Correct usageconsole.log(userName);// Output: Hello userName =123;// Correct usageconsole.log(userName);// Output: 123

    On compiling, it will generate the following JavaScript code.

    let userName;
    userName ="Hello";// Correct usageconsole.log(userName);// Output: Hello
    userName =123;// Correct usageconsole.log(userName);// Output: 123

    Output

    Hello
    123
    

    Example: Indexed Access with Arrays

    When you want to access the type of the array elements, you can use the ‘number’ as an index.

    In the code below, we have defined the StringArray type, which contains the array of the string.

    The ‘StringArray[number]’ gets the type of the array element, which is a string.

    typeStringArray=string[];// Access the type of an array elementtypeElementType= StringArray[number];// type is stringlet element: ElementType;
    element ="Hello";// Correct usageconsole.log(element);// element = 123;    // Error: Type 'number' is not assignable to type 'string'.

    On compiling, it will generate the following JavaScript code.

    let element;
    element ="Hello";// Correct usageconsole.log(element);// element = 123;    // Error: Type 'number' is not assignable to type 'string'.

    Output

    Hello
    

    This way you can access the type of the properties of the existing types using the indexed access type. You can also use the ‘number’ property to access the type of the array elements.

  • Typeof Type Operator

    In TypeScript, the typeof is one of the most helpful operators and keywords to check the types of variables or identifiers. However, TypeScript is a type-strict language. So, we need to define the type of the variable or object while defining the identifier itself. Still, sometimes we need to check the type of the variable.

    For example, we are taking the data from the user via forms and handling it via TypeScript. Then we have to validate the data and perform some database operations. Also, the identifier can have multiple types in TypeScript. So, using the typeof operator, we can check the identifier type after initializing it.

    Syntax

    The below syntax demonstrates the use of typeof operator with the identifiers.

    let type = typeof <variable>
    

    Where,

    • variable is an identifier, for which we need to check the type.

    Return Value

    It returns a string according to the data type of the operand of the typeof operator.

    Examples

    Let’s understand the typeof operator with the help of examples in TypeScript −

    Example 1

    In this example, we have used the typeof operator with the string, number, boolean, and undefined variables. Also, we used the typeof operator with the variable containing the null as a value.

    In the output, we can see that It returns the string representing the type of the identifier. For the null_value1 identifier, the typeof operator returns the object.

    // Defining the variables of particular type and checking its type.let str1: string ="TutorialsPoint";
    console.log(typeof str1);let num1: number =32;
    console.log(typeof num1);let bool1: boolean =true;
    console.log(typeof bool1);let un_defined;
    console.log(typeof un_defined);let null_value1 =null;
    console.log(typeof null_value1);

    On compiling, it will generate the following JavaScript code

    // Defining the variables of particular type and checking its type.var str1 ="TutorialsPoint";
    console.log(typeof str1);var num1 =32;
    console.log(typeof num1);var bool1 =true;
    console.log(typeof bool1);var un_defined;
    console.log(typeof un_defined);var null_value1 =null;
    console.log(typeof null_value1);

    Output

    The above code will produce the following output

    string
    number
    boolean
    undefined
    object
    

    Example 2

    In the example below, we have created the objection containing some key-value pairs, a function returning the number value, and an array of numbers that contains different values.

    Also, we used the typeof operator to check the type of all. The typeof operator returns the “object” string for the object, the “function” string for the Function, and the “object” string for the array, as the array is the instance of the object.

    // using the typeof operator with object, function, and array.let demo_obj ={
       prop:"value",};
    console.log(typeof demo_obj);functionfunc(){let a =10+20;return a;}
    console.log(typeof func);let array: Array<number>=[4,23,212,2123,323,3];
    console.log(typeof array);

    On compiling, it will generate the following JavaScript code

    // using the typeof operator with object, function, and array.var demo_obj ={
       prop:"value"};
    console.log(typeof demo_obj);functionfunc(){var a =10+20;return a;}
    console.log(typeof func);var array =[4,23,212,2123,323,3];
    console.log(typeof array);

    Output

    The above code will produce the following output

    object
    function
    object
    

    Example 3

    In this example, we checked the type of the NaN keyword using the typeof operator, which returns the “number” string. The type of negative Infinity is also a number. The PI is the property of the Math class, which contains the number value. Thats why the typeof operator returns “number” for the Math.PI property.

    The pow() is the Math library function to get the power of any numbers. So, the typeof operator returns the “function” for the Math.pow() method.

    // using the typeof operator with NaN, infinity, library methods, and members.let NaN_type =NaN;
    console.log(typeof NaN_type);let infi =-Infinity;
    console.log(typeof infi);let pI = Math.PI;
    console.log(typeof pI);let pow = Math.pow;
    console.log(typeof pow);

    On compiling, it will generate the following JavaScript code

    // using the typeof operator with NaN, infinity, library methods, and members.var NaN_type =NaN;
    console.log(typeof NaN_type);var infi =-Infinity;
    console.log(typeof infi);var pI = Math.PI;
    console.log(typeof pI);var pow = Math.pow;
    console.log(typeof pow);

    Output

    The above code will produce the following output

    number
    number
    number
    function
    

    Example 4

    In this example, we used the typeof operator to get the type of variable1 and defined variable2 of the same type as variable1. Also, we used the type alias to store the type of variable3. The type named type1 contains the type of variable3, which is a string.

    After that, we used type1 to define the type of variable4. In the output, users can observe that the type of variable4 is the same as variable3.

    // defining the variable1 of type numbervar variable1: number =10;// To define the variable2 as of same type variable1let variable2:typeof variable1 =20;
    console.log(typeof variable2);// variable3 of string typevar variable3: string ="Hello!";// using the type alias to define the type of same type as variable3
    type type1 =typeof variable3;// defining the variable4 of type named type1let variable4: type1 ="Hi";
    console.log(typeof variable4);

    On compiling, it will generate the following JavaScript code

    // defining the variable1 of type numbervar variable1 =10;// To define the variable2 as of same type variable1var variable2 =20;
    console.log(typeof variable2);// variable3 of string typevar variable3 ="Hello!";// defining the variable4 of type named type1var variable4 ="Hi";
    console.log(typeof variable4);

    Output

    The above code will produce the following output

    number
    string
    
  • Keyof Type Operator

    In TypeScript, the keyof type operator allows you to obtain the keys of an object and use them to perform various operations. It plays a significant role when working with objects and their properties.

    Syntax

    The syntax of the keyof type operator in TypeScript is as follows

    keyof Type
    

    The keyof keyword is followed by the name of a type, referred to as “Type.” It returns a union type consisting of all the keys (property names) of the specified type. This allows you to access and manipulate an object’s keys dynamically.

    Examples

    Let’s understand the keyof operator with the help of some examples in TypeScript.

    Example 1: Accessing Object Property Names

    The keyof keyword helps us retrieve the names of properties defined within an object type.

    In this example, we define an interface called “Person” with two properties: “name” of type string and “age” of type number.

    Then we create a type alias “PersonKeys” using keyof to extract the keys from the Person interface.

    Finally, we assign the value ‘name’ to a constant named “keys” of type PersonKeys and log its value.

    interfacePerson{
       name: string;
       age: number;}
    
    type PersonKeys = keyof Person;const keys: PersonKeys ='name';
    console.log(keys);

    On compiling, it will generate the following JavaScript code

    var keys ='name';
    console.log(keys);

    Output

    The above code will produce the following output

    name
    

    Example: Type-Safe Property Access

    The keyof keyword enables us to access object properties in a type-safe manner.

    In this example, we define an interface “Car” with properties representing a car’s brand, year, and price. We declare a generic function called “getProperty” that takes two arguments: “obj” of type T and “key” of type K, where K extends keyof T. The function returns the value corresponding to the given key in the object. We then create a car object and use the “getProperty” function to retrieve the car’s brand property and assign it to the “carBrand” variable. Finally, we log the value of “carBrand.

    interfaceCar{
       brand: string;
       year: number;
       price: number;}function getProperty<T,KextendskeyofT>(obj:T, key:K):T[K]{return obj[key];}const car: Car ={
       brand:'Toyota',
       year:2022,
       price:25000,};const carBrand: string =getProperty(car,'brand');
    console.log(carBrand);

    On compiling, it will generate the following JavaScript code

    functiongetProperty(obj, key){return obj[key];}var car ={
       brand:'Toyota',
       year:2022,
       price:25000};var carBrand =getProperty(car,'brand');
    console.log(carBrand);

    Output

    The above code will produce the following output

    Toyota
    

    Example 3: Mapping Object Properties

    The keyof keyword is also useful for mapping properties from one object to another. In this example, we define an interface “Fruit” with properties representing the name and color of the fruit. We then create a new type, “FruitMapped” using the keyof within a mapped type. It maps each key in keyof Fruit to the type “string”. Finally, we create a “fruit” object using the FruitMapped type and log its value.

    interfaceFruit{
       name: string;
       color: string;}
    
    type FruitMapped ={[Kin keyof Fruit]: string;};const fruit: FruitMapped ={
       name:'Apple',
       color:'Red',};
    
    console.log(fruit);

    On compiling, it will generate the following JavaScript code

    var fruit ={
       name:'Apple',
       color:'Red'};
    console.log(fruit);

    Output

    The above code will produce the following output

    { name: 'Apple', color: 'Red' }
    

    Example 4: Conditional Type Mapping

    Another powerful application of the keyof keyword is in conditional type mapping. This allows us to selectively map properties based on certain conditions. In this example, we have an interface “Product” representing a product’s name, price, and availability. We define a type “DiscountedProducts” that utilizes conditional mapping using keyof. It checks if the property’s value extends the “number” type and maps it to the union type of the original value and “null”. For all other property types, it keeps the original value type unchanged. Finally, we create a “product” object using the DiscountedProducts type.

    interfaceProduct{
       name: string;
       price: number;
       inStock: boolean;}
    
    type DiscountedProducts<T>={[Kin keyof T]:T[K]extendsnumber?T[K]|null:T[K];};const product: DiscountedProducts<Product>={
       name:'Widget',
       price:10,
       inStock:true,};
    
    console.log(product);

    On compiling, it will generate the following JavaScript code

    var product ={
       name:'Widget',
       price:10,
       inStock:true};
    console.log(product);

    Output

    The above code will produce the following output

    { name: 'Widget', price: 10, inStock: true }
    
  • Creating Types from Types

    TypeScript allows you to create custom types from the existing or built-in types. Creating types from existing types helps you to make code more maintainable and error-resistant.

    TypeScript is a statically typed language. This means that ideally, each variable, function parameter, and object property should be explicitly assigned a type.

    Here we will discuss different ways to create custom types from the existing types.

    Union Types

    If you want to define a single variable that can store the value of multiple data types, you can use the union operator to combine multiple operators. The union operator is ‘|’, and using that you can combine multiple types.

    Syntax

    You can follow the syntax below to create custom types by using the union operator.

    typeunionTypes= type1 | type2 | type3 |...;

    In the above syntax, type1, type2, type3, etc. are data types.

    Example

    In the code below, we have defined the ‘StringOrNumber’ custom type which is a union of the string and number data type.

    The processValue() function takes the single parameter of the type ‘StringOrNumber’. In the function body, we check the type of the parameter using the ‘typeof’ operator, and based on the string or numeric type, we print the value in the output console.

    // Defining a union typetypeStringOrNumber=string|number;// Function that accepts a union type as an argumentfunctionprocessValue(value: StringOrNumber){// Check if the value is a string or number typeif(typeof value ==="string"){console.log(String: ${value});}else{console.log(Number: ${value});}}processValue("hello");// Output: String: helloprocessValue(123);// Output: Number: 123

    On compiling, it will generate the following JavaScript code.

    // Function that accepts a union type as an argumentfunctionprocessValue(value){// Check if the value is a string or number typeif(typeof value ==="string"){console.log(String: ${value});}else{console.log(Number: ${value});}}processValue("hello");// Output: String: helloprocessValue(123);// Output: Number: 123

    The output of the above example code is as follows

    String: hello
    Number: 123
    

    Intersection Types

    The intersection operator (&) allows you to combine the multiple types in the single types. For example, if you have two interfaces or types for Business and contactDetails, and want to combine both types, you can use the intersection operator.

    Syntax

    You can follow the syntax below to create custom types by using the intersection operator.

    typeintersectionTypes= type1 & type2 & type3 &...;

    In the above syntax, we have combined multiple types using the intersection operator.

    Example

    In the code below, we have defined the ‘Business’ interface containing the name and turnover properties. We have also defined the contactDetails interface containing the email and phone properties.

    After that, we combined both types using the intersection operator and stored them in the ‘BusinessContact’ type. Next, we have defined the object of the type ‘BusinessContact’, and logged it in the console.

    // Defining a business typeinterfaceBusiness{
    
    name:string;
    turnover:number;}// Defining a contact details typeinterface ContactDetails {
    email:string;
    phone:string;}// Intersection of two typestypeBusinessContact= Business &amp; ContactDetails;// Creating an object of the type BusinessContactlet contact: BusinessContact ={
    name:"EnviroFront",
    turnover:5000000,
    email:"[email protected]",
    phone:"1234567890"};console.log(contact);</code></pre>

    On compiling, it will generate the following JavaScript code.

    // Creating an object of the type BusinessContactlet contact ={
    
    name:"EnviroFront",
    turnover:5000000,
    email:"[email protected]",
    phone:"1234567890"};console.log(contact);</code></pre>

    The output of the above example code is as follows

    {
      name: 'EnviroFront',
      turnover: 5000000,
      email: '[email protected]',
      phone: '1234567890'
    }
    

    Utility types

    TypeScript contains multiple utility types, which makes it easy to transform the particular types and create new types. Let's look at some of the utility types with examples.

    Syntax

    You can follow the syntax below to use any utility type.

    Utility_type_name<typeorinterface>

    In the above syntax, 'utility_type_name' can be replaced with 'Partial', 'Pick', 'Record', etc. based on which utility type you are using. Here, 'type' or 'interface' is the name of the interface from which you want to create a new custom type.

    Partial Utility Type

    The partial utility type makes all properties of the interface or type option. So, you can create a new type having all properties optional from the existing type.

    Example

    In the code below, we have defined the 'Todo' interface. After that, we used the Partial utility type to create a new type using the Todo interface by making all properties of it optional.

    Next, we have defined the object of the 'OptionalTodo' type, which contains only the 'title' property, as the 'description' property is optional.

    // Defining an interface for Todo list interfaceTodo{
    
    title:string;
    description:string;}// Defining a custom type using the Partial utility typetypeOptionalTodo= Partial&lt;Todo&gt;;// Creating an object of type OptionalTodolet todo: OptionalTodo ={ title:"Buy milk"};// 'description' is optionalconsole.log(todo);</code></pre>

    On compiling, it will generate the following JavaScript code.

    // Creating an object of type OptionalTodolet todo ={ title:"Buy milk"};// 'description' is optionalconsole.log(todo);

    The output of the above example code is as follows

    { title: 'Buy milk' }
    

    Pick Utility Type

    The Pick utility type allows one to pick a subset of properties from the existing types. Let's understand it via the example below.

    Example

    In the code below, we have defined the 'ToDo' interface and used the Pick utility type to create a new type with only the 'title' property from the 'ToDo' interface. Here, the 'ToDoPick' type contains only the 'title' property.

    // Defining an interface for Todo list interfaceTodo{
    
    title:string;
    description:string;}// Defining a custom type using the Pick utility typetypeTodoPick= Pick&lt;Todo,"title"&gt;;let myTodo: TodoPick ={ title:"Write a code"};console.log(myTodo.title);</code></pre>

    On compiling, it will generate the following JavaScript code.

    let myTodo ={ title:"Write a code"};console.log(myTodo.title);

    The output of the above example code is as follows

    Write a code
    

    Typeof Type Operator

    The typeof operator is used to get the type of the particular variable. You can use the typeOf variable to extract the data type of the particular variable, object, function, etc., and use the data type for other variables.

    Syntax

    You can follow the syntax below to create custom types by using the typeof type operator.

    Typeof variable;

    In the above syntax, 'variable' can be an object, function, etc.

    Example

    In the code below, we have defined the person object containing the name and gender properties. After that, we used the 'typeof' operator to get the type of the person object and stored it in the 'employee' type variable.

    After that, we have defined the 'employee1' object of the 'employee' type, which contains the name and gender properties.

    // Defining a person objectconst person ={
    
    name:"John",
    gender:"male"};// Defining a type employeetypeemployee=typeof person;// Type is { url: string; timeout: number; }// Defining an employee objectlet employee1: employee ={
    name:"Sbv",
    gender:"male"};console.log(employee1);</code></pre>

    On compiling, it will generate the following JavaScript code.

    // Defining a person objectconst person ={
    
    name:"John",
    gender:"male"};// Defining an employee objectlet employee1 ={
    name:"Sak",
    gender:"male"};console.log(employee1);</code></pre>

    The output is as follows

    { name: 'Sak', gender: 'male' }
    

    Creating a custom type allows you to reuse the existing types and write maintainable code. You may use the union or intersection operator if you want to provide an optional type or combine multiple types. Furthermore, you can use the utility types and typeof operator to create custom types from the existing types.

  • Type Assertions

    Type assertion is a mechanism in TypeScript that informs the compiler of the variable type. We can override the type using a type assertion if TypeScript finds that the assignment is wrong. We must be certain that we are correct since the assignment is always legitimate when we employ a type assertion. If not, our program might not operate properly.

    Type assertion functions similarly to typecasting, but unlike C# and Java, it does not do type verification or data rearrangement. Runtime support is provided for typecasting, although type assertion does not affect runtime. Type assertions are solely a compile-time construct to give the compiler indications about how we want our code to be inspected.

    How to Perform Type Assertions?

    Type assertion is a Typescript technique that tells the compiler about the type of variable. Though type assertion doesnt recreate code, typecasting does. You can tell the compiler not to infer the type of a value by using type assertion. We utilize Type assertion to convert a variable from one type to another, such as any to a number. To do type assertion, we can either use the “<>” operator or the “as” operator. Typecasting provides runtime support, whereas type assertion has no impact on runtime. There are three techniques to perform Type Assertion in TypeScript, and those are:

    • Using as operator
    • Using <> operator
    • Using object

    Using as Operator for Type Assertion

    The as keyword in TypeScript offers a method for displaying Type Assertion.

    Syntax

    let variable_any:any=123let variable_number:number= variable_any asnumber

    In the above syntax, we used the “as” keyword on any type variable for type assertion.

    Example

    let variable_unknown:unknown="Tutorialspoint";console.log("variable_unknown value is: ", variable_unknown);let variable_number:number=(variable_unknown asstring).length;console.log("Length of variable_unknown: ", variable_number);

    On compiling, it will generate the following JavaScript code:

    var variable_unknown ="Tutorialspoint";console.log("variable_unknown value is: ", variable_unknown);var variable_number = variable_unknown.length;console.log("Length of variable_unknown: ", variable_number);

    The output will be:

    variable_unknown value is: Tutorialspoint
    Length of variable_unknown: 14
    

    Using <> Operator for Type Assertion

    The <> operator is another way to perform type assertion in TypeScript.

    Syntax

    let variable_any:any=123let variable_number:number=<number> variable_any
    

    In the above syntax, we used the “<>” operator on any type variable for type assertion.

    Example

    let my_number:unknown=12345console.log('my_number value is: ', my_number)let num:number=<number>my_number
    console.log('typeof num is: ',typeof num)

    On compiling, it will generate the following JavaScript code:

    var my_number =12345;console.log('my_number value is: ', my_number);var num = my_number;console.log('typeof num is: ',typeof num);

    The output will be:

    my_number value is: 12345
    typeof num is: number
    

    Using Object for Type Assertion

    Objects are another way to perform the type assertion, unlike the “as” and “<>” operators; the objects can use for multiple type assertions at once.

    Syntax

    interfaceinfo{
       name:string,
       value:string}let my_obj =<info>{ name:'ABC', value:'abc'}

    In the above syntax, we used the object to perform type assertion.

    Example

    interfaceinfo{
       name:string
       value:string}let my_obj =<info>{}
    my_obj.name ='Tutorialspoint'
    my_obj.value ='typescript'console.log(my_obj)

    On compiling, it will generate the following JavaScript code:

    var my_obj ={};
    my_obj.name ='Tutorialspoint';
    my_obj.value ='typescript';console.log(my_obj);

    The output will be:

    { name: 'Tutorialspoint', value: 'typescript' }
  • Type Guards

    In TypeScript, the type guards are used to determine a variable’s type, often inside a conditional or functional block. The type guards usually take the variable and return a Boolean value or the variable type. Type guards allow you to tell the TypeScript compiler to infer a given type for a variable in a specific context, guaranteeing that an argument’s type is what you say it is.

    Similar to feature detection, type guards are commonly used to narrow down a type, enabling you to identify the appropriate prototypes, methods, and attributes of a value. As a result, handling that value become simple for the user.

    The user-defined type guards can be created in TypeScript, but it also has built-in operators like the ‘typeof’, ‘in’, and the ‘instanceof’ operator.

    The ‘typeof’ type guard in TypeScript

    In TypeScript, the ‘typeof’ operator is used to get the type of the variable. According to the variable’s type, it returns the values like

    • Number
    • String
    • Boolean
    • Object
    • Bigint
    • Symbol
    • Function
    • Undefined

    Syntax

    Users can follow the below syntax to use the ‘typeof’ type, guard operator.

    typeof variable_name
    

    In the above syntax, we use the typeof operator just before the variable name to get the variable type.

    Example

    In the following example, we will use the ‘typeof’ type guard in TypeScript. We have declared four variables of types’ number’, ‘string’, ‘boolean’, and ‘object’. After that, we console log their variable type using the ‘typeof’ operator of the TypeScript.

    let my_number:number=123let my_string:string='Tutorialspoint'let my_boolean:boolean=truelet my_object:{ id:number}={ id:1}console.log('type of my_number variable is: '+typeof my_number)console.log('type of my_string variable is: '+typeof my_string)console.log('type of my_boolean variable is: '+typeof my_boolean)console.log('type of my_object variable is: '+typeof my_object)

    On compiling, it will generate the following JavaScript code

    var my_number =123;var my_string ='Tutorialspoint';var my_boolean =true;var my_object ={ id:1};
    console.log('type of my_number variable is: '+typeof my_number);
    console.log('type of my_string variable is: '+typeof my_string);
    console.log('type of my_boolean variable is: '+typeof my_boolean);
    console.log('type of my_object variable is: '+typeof my_object);

    Output

    The above code will produce the following output

    type of my_number variable is: number
    type of my_string variable is: string
    type of my_boolean variable is: boolean
    type of my_object variable is: object
    

    In the above output, users can see the output of the ‘typeof’ operator for four variables: ‘number’, ‘string’, ‘boolean’, and ‘object’.

    The ‘in’ type guard in TypeScript

    The ‘in’ type guard determines if an object contains a specific attribute, which is then used to distinguish between distinct types. It typically returns a boolean, indicating if the property is present in the object. It is utilized for its narrowing characteristics.

    Syntax

    Users can follow the below syntax to use the ‘in’ type guard operator.

    property_name in object_name
    

    In the above syntax, we use the ‘in’ operator to find whether the property exists in the object.

    Example

    In the following example, we will use the ‘in’ type guard in TypeScript. We have declared three objects that consist of different properties. We use the’ in’ type guard to check whether a required property exists in the object. We can even check if a property contains another property or if it is not using it. In the ‘obj3’, we check if an object’s property contains another property or not.

    let obj1:{ id:number; name:string}={ id:1, name:'Tutorialspoint'}let obj2:{ name:string; roll:number}={ name:'XYZ', roll:12}let obj3:{ id:number; marks:{ english:number; math:number}}={
       id:101,
       marks:{
    
      math:90,
      english:80,},}console.log('Is name in obj1? =&gt; '+('name'in obj1))console.log('Is id obj2? =&gt; '+('id'in obj2))console.log('Is marks in obj3? =&gt; '+('marks'in obj3))console.log('Is math in obj3.marks? =&gt; '+('math'in obj3.marks))</code></pre>

    On compiling, it will generate the following JavaScript code

    var obj1 ={ id:1, name:'Tutorialspoint'};var obj2 ={ name:'XYZ', roll:12};var obj3 ={
       id:101,
       marks:{
    
      math:90,
      english:80}};
    console.log('Is name in obj1? => '+('name'in obj1)); console.log('Is id in obj2? => '+('id'in obj2)); console.log('Is marks in obj3? => '+('marks'in obj3)); console.log('Is math in obj3.marks? => '+('math'in obj3.marks));

    Output

    The above code will produce the following output

    Is name in obj1? => true
    Is id in obj2? => false
    Is marks in obj3? => true
    Is math in obj3.marks? => true
    

    In the above output, users can see the output of the 'in' operator in different circumstances in our code.

    The 'instanceof' type guard in TypeScript

    The 'instanceof' is a built-in type guard used to determine whether a value is an instance of a specific constructor function or class. We may use this type-guard to determine the type of instance type by testing if an object or value is derived from a class.

    Syntax

    Users can follow the below syntax to use the 'instanceof' type-guard operator.

    object_name instanceof class_name
    

    In the above syntax, we use the 'instanceof' operator to find whether the object is an instance of the class.

    Example

    In the following example, we will use the 'instanceof' type guard in TypeScript. We have declared a 'Parent' class and a child classe, 'Child'. We declare an objects of the 'Child' class and use the 'instanceof' operator to find the object belongs to which class.

    classParent{
       id:numberconstructor(id:number){this.id = id
       }}classChildextendsParent{
       id:number
       name:stringconstructor(id:number, name:string){super(id)this.name = name
       }}let child =newChild(101,'ABC')console.log('child instanceof Child => '+(child instanceofChild))console.log('child instanceof Parent => '+(child instanceofParent))

    On compiling, it will generate the following JavaScript code

    var __extends =(this&&this.__extends)||(function(){varextendStatics=function(d, b){
    
      extendStatics = Object.setPrototypeOf ||({ __proto__:&#91;]}instanceofArray&amp;&amp;function(d, b){ d.__proto__ = b;})||function(d, b){for(var p in b)if(b.hasOwnProperty(p)) d&#91;p]= b&#91;p];};returnextendStatics(d, b);};returnfunction(d, b){extendStatics(d, b);function__(){this.constructor = d;}
      d.prototype = b ===null? Object.create(b):(__.prototype = b.prototype,new__());};})();var Parent =/** @class */(function(){functionParent(id){this.id = id;}return Parent;}());var Child =/** @class */(function(_super){__extends(Child, _super);functionChild(id, name){var _this =_super.call(this, id)||this;
      _this.name = name;return _this;}return Child;}(Parent));var child =newChild(101,'ABC');
    console.log('child instanceof Child => '+(child instanceofChild)); console.log('child instanceof Parent => '+(child instanceofParent));

    Output

    The above code will produce the following output

    child instanceof Child => true
    child instanceof Parent => true
    

    In the above output, users can see the output of the 'instanceof' operator when used in different classes and their objects.

  • Intersection Types

    In TypeScript, an intersection type combines multiple types into one. Although intersection and union types in TypeScript are similar, they are used in very different ways. A type that combines different types into one is called an intersection type. This enables you to combine many types to produce a single type with all the necessary attributes. Members from each of the provided types will be present in an object of this type. The intersection type is made using the ‘&’ operator.

    When two types intersect in TypeScript, the intersection type will inherit the characteristics of both intersecting types. Take caution when combining types that share property names with different kinds.

    Syntax

    We can write the below syntax to create an Intersection type in TypeScript.

    typeintersepted_Type= Type1 & Type2;

    Example

    In the example below, we have created two interfaces named “Book” and “Author”. Now inside the Book, we have created two fields named “book_id”, which is of number type, and “book_name”, which is of string type. And inside the Author, we have also created two fields named “author_id”, which is of number type, and “author_name”, which is of string type. Next, we intersected the Book and Author interface and stored it into intersected_types. Finally, values are retrieved from an object of the intersection type created.

    interfaceBook{
       book_id:number
       book_name:string}interfaceAuthor{
       author_id:number
       author_name:string}typeintersected_type= Book & Author
    let intersected_type_object1: intersected_type ={
       book_id:101,
       book_name:'Typescript is Awesome',
       author_id:202,
       author_name:'Tutorialspoint!',}console.log('Book Id: '+ intersected_type_object1.book_id)console.log('Book name: '+ intersected_type_object1.book_name)console.log('Author Id: '+ intersected_type_object1.author_id)console.log('Author name: '+ intersected_type_object1.author_name)

    On compiling, it will generate the following JavaScript code

    var intersected_type_object1 ={
       book_id:101,
       book_name:'Typescript is Awesome',
       author_id:202,
       author_name:'Tutorialspoint!'};
    console.log('Book Id: '+ intersected_type_object1.book_id);
    console.log('Book name: '+ intersected_type_object1.book_name);
    console.log('Author Id: '+ intersected_type_object1.author_id);
    console.log('Author name: '+ intersected_type_object1.author_name);

    Output

    The above code will produce the following output

    Book Id: 101
    Book name: Typescript is Awesome
    Author Id: 202
    Author name: Tutorialspoint!
    

    As users can see in the output, all the values of two different interfaces are combined and displayed.

    Intersection types are Associative and Commutative

    The commutative property indicates that an equation’s factors can be freely rearranged without altering the equation’s outcome.

    commutative property:  (A & B) = (B & A)

    Associative property asserts that altering how integers are grouped during an operation will not affect the equation’s solution.

    associative property: (A & B) & C = A & (B & C)

    When we cross two or more kinds, it doesn’t matter what order they are in. The ‘typeof’ operator is used to verify that the attributes of the intersected objects are also the same, regardless of how the items are intersected or in what order.

    Example

    As we can see in the below example, here we have created three interfaces named “Student”, “Class”, and “Subject”. Now inside the Student, we have created two fields called “student_id”, which is of number type, and “sudent_name”, which is of string type. Inside the “Class” instance, we have also created two fields named “class_id”, which is of number type, and “class_name”, which is of string type. Inside the “Subject” instance, we have also created two fields named “subject_id”, which is of number type, and “subject_name”, which is of string type.

    Next, we intersected the Book, Author, and Subject interface using associative property and stored it into intersected types. After that, values are retrieved from an object of the intersection type created. Finally, we checked the objects using the typeof operator and logged in to the console.

    interfaceStudent{
       student_id:number
       student_name:string}interfaceClass{
       class_id:number
       class_name:string}interfaceSubject{
       subject_id:number
       subject_name:string}typeintersected_type_1=(Student & Class)& Subject
    typeintersected_type_2= Student &(Class & Subject)let intersected_type_object1: intersected_type_1 ={
       student_id:101,
       student_name:'Typescript',
       class_id:10,}let intersected_type_object2: intersected_type_2 ={
       student_id:102,
       student_name:'Typescript2',
       class_id:11,}console.log(typeof intersected_type_object1 ===typeof intersected_type_object2)

    On compiling, it will generate the following JavaScript code

    var intersected_type_object1 ={
       student_id:101,
       student_name:'Typescript',
       class_id:10};var intersected_type_object2 ={
       student_id:102,
       student_name:'Typescript2',
       class_id:11};
    console.log(typeof intersected_type_object1 ===typeof intersected_type_object2);

    Output

    The above code will produce the following output

    true
    

    As users can see in the output, both the attributes of the objects are identical, showing the true value.

  • Duck Typing

    Duck Typing

    The circumstance where an object’s type is decided by its behavior, like methods and attributes, rather than its class is known as “duck typing”.

    The usage of interfaces in TypeScript makes duck typing possible. Where interface means the set of methods and characteristics an object must have to fall under that type are described.

    For example, if an interface defines the function, any object with the method called “myFunc()” may be treated as belonging to a specific kind, regardless of its class.

    Duck typing emphasizes assessing an object’s suitability for a task by considering its methods and attributes instead of its actual type. An interface explains the set of properties and methods an object must have to be considered “duck typed” for a particular purpose.

    Benefits of Duck Typing

    One of duck typing’s main benefits is making code more flexible and reusable. The code works with any object with the required methods and properties rather than just particular types of objects and may be used in various situations without requiring modification. Duck typing also improves code reuse by enabling the interchangeable usage of objects of diverse kinds within a single codebase.

    Exmaples of Duck Typing is TypeScript

    Here is an example of how to use duck typing in TypeScript

    Define an interface that represents the behaviour you want an object to have. For example

    interfaceDuck{quack():void;}

    Create a class that implements the interface. For example

    classMallardDuckimplementsDuck{quack():void{
    
      console.log("Quack!");}}</code></pre>

    Create an instance of the class and use it as the type defined by the interface.

    let duck: Duck =newMallardDuck();
    duck.quack();// Output: "Quack!"

    Create another class that also implements the interface

    classRubberDuckimplementsDuck{quack():void{
    
      console.log("Squeak!");}}</code></pre>

    Use the new class instance as the same type defined by the interface.

    let duck: Duck =newRubberDuck();
    duck.quack();// Output: "Squeak!"

    As you can see, both MallardDuck and RubberDuck classes implement the Duck interface, and the duck variable can be assigned to instances of both classes. The type is determined by the behaviour (methods and properties) defined in the interface rather than the class.

    It's also important to note that in typescript, you can use the typeof keyword to check the type of object in runtime and if the object has the expected method or property.

    Example

    In this example, the Bird and Plane classes implement the Flyable interface, which requires a fly() method. Both "duck types" can be used interchangeably in the goFly() function. The function doesn't care about the actual type of the object passed to it as long as it has a fly() method that can be called.

    interfaceFlyable{fly():void;}classBirdimplementsFlyable{fly():void{
    
      console.log("Bird is flying");}}classPlaneimplementsFlyable{fly():void{
      console.log("Plane is flying");}}functiongoFly(flyable: Flyable){
    flyable.fly();}let bird =newBird();let plane =newPlane();goFly(bird);// Prints "Bird is flying"goFly(plane);// Prints "Plane is flying"

    On compiling, it will generate the following JavaScript code

    var Bird =/** @class */(function(){functionBird(){}
       Bird.prototype.fly=function(){console.log("Bird is flying");};return Bird;}());var Plane =/** @class */(function(){functionPlane(){}
       Plane.prototype.fly=function(){console.log("Plane is flying");};return Plane;}());functiongoFly(flyable){
       flyable.fly();}var bird =newBird();var plane =newPlane();goFly(bird);// Prints "Bird is flying"goFly(plane);// Prints "Plane is flying"

    Output

    The above code will produce the following output

    Bird is flying
    Plane is flying
    

    Example

    Overall, duck typing is a powerful programming concept that allows for greater flexibility and reusability in TypeScript code by allowing objects of different types to be used interchangeably as long as they have the same methods and properties. In this example, the Driveable interface, Car and Truck classes show the same thing.

    interfaceDriveable{drive():void;}classCarimplementsDriveable{drive():void{
    
    console.log("Car is driving");}}classTruckimplementsDriveable{drive():void{
    console.log("Truck is driving");}}functiongoDrive(driveable: Driveable){
    driveable.drive();}let car =newCar();let truck =newTruck();goDrive(car);// Prints "Car is driving"goDrive(truck);// Prints "Truck is driving"

    On compiling, it will generate the following JavaScript code

    var Car =/** @class */(function(){functionCar(){}
    
    Car.prototype.drive=function(){console.log("Car is driving");};return Car;}());var Truck =/** @class */(function(){functionTruck(){}
    Truck.prototype.drive=function(){console.log("Truck is driving");};return Truck;}());functiongoDrive(driveable){
    driveable.drive();}var car =newCar();var truck =newTruck();goDrive(car);// Prints "Car is driving"goDrive(truck);// Prints "Truck is driving"</code></pre>

    Output

    The above code will produce the following output

    Car is driving
    Truck is driving
    

    The main idea behind duck typing is that the code should be written to work with any object with the methods and properties it needs, rather than being written to work with specific objects. This can make the code more flexible and reusable, allowing you to use different types of objects interchangeably without changing the code.

  • Accessors

    Accessors in TypeScript provides a way to access and set the value of the class members using the getter and setter methods. They control how class members are accessed to read or write their values.

    Accessors are useful for achieving encapsulation in TypeScript, which restricts access to class members only to the member functions of the class, preventing unauthorized access via third parties.

    TypeScript supports the followings to access and change class members:

    • getters
    • setters

    Getters in TypeScript

    Getters are used to access the values of class members and manage how these values are accessed outside of the class. They can be created using the ‘get’ keyword.

    Syntax

    You can follow the syntax below to use getters in TypeScript.

    classclass_name{// Define private variable here.// Defining the gettergetgetter_name(): return_type {// Return variable value}}let val = class_name.getter_name;

    In the above syntax, the method_name method is a static method, which can take multiple parameters and return a value.

    To access the value using the getter, we can use the class name followed by a dot followed by the getter method name.

    Example

    In the example below, we have defined the Person class, which contains the ‘Name’ private variable. It also contains the constructor() method which initializes the value of the ‘Name’ variable.

    // Defining the Person classclassPerson{// Defining the private fieldprivate Name:string;// Defining the constructorconstructor(Name:string){this.Name = Name;}// Defining the gettergetSName():string{returnthis.Name;}}// Creating an instance of the Person classconst person =newPerson("John");console.log(person.SName);// Outputs: John

    On compiling, it will generate the following JavaScript code.

    // Defining the Person classclassPerson{// Defining the constructorconstructor(Name){this.Name = Name;}// Defining the gettergetSName(){returnthis.Name;}}// Creating an instance of the Person classconst person =newPerson("John");console.log(person.SName);// Outputs: John

    Output

    John
    

    Example

    In the code below, the Temperature class contains the ‘celsius’ private variable. The constructor() method initializes the value of the ‘celsius’ variable.

    // Define a class Temperature with a property Celsius of type number.classTemperature{private celsius:number;// Define a constructor that initializes the Celsius property.constructor(celsius:number){this.celsius = celsius;}// Define a getter fahrenheit that returns the temperature in Fahrenheit.getfahrenheit():number{return(this.celsius *9/5)+32;}}// Create an instance of the Temperature class with a temperature of 25 degrees Celsius.const temp =newTemperature(25);console.log("The Fahrenheit value is: "+ temp.fahrenheit);// Outputs: 77

    On compiling, it will generate the following JavaScript code.

    // Define a class Temperature with a property Celsius of type number.classTemperature{// Define a constructor that initializes the Celsius property.constructor(celsius){this.celsius = celsius;}// Define a getter fahrenheit that returns the temperature in Fahrenheit.getfahrenheit(){return(this.celsius *9/5)+32;}}// Create an instance of the Temperature class with a temperature of 25 degrees Celsius.const temp =newTemperature(25);console.log("The Fahrenheit value is: "+ temp.fahrenheit);// Outputs: 77

    Output

    The Fahrenheit value is: 77
    

    Setters in TypeScript

    In TypeScript, setters are used to set the value of class members without accessing them outside of the class. They use the ‘set’ keyword to define the setter method.

    Syntax

    You can follow the syntax below to use setters in TypeScript.

    classclass_name{// Define private variable here.// Defining the settersetsetter_name(val: type){// Set variable value}}
    
    class_name.setter_name = val;

    In the above syntax, we have used the ‘set’ keyword followed by ‘setter_name’ to define a setter. It takes only a single value as a parameter and uses it inside the setter method to change the value of any private class variables.

    To use the setter method, you need to use the class name followed by a dot followed by the setter method name and assign a value to it.

    Example

    In the code below, we have defined the TextContainer class, which contains the ‘_content’ private variable to store the text.

    // Define a class with a private property and a getter/setter methodclassTextContainer{// Define a private propertyprivate _content:string='';// Setter methodsetcontent(value:string){this._content = value.trim().toLowerCase();}// Getter methodgetcontent():string{returnthis._content;}}// Create an instance of the class and set the contentconst text =newTextContainer();
    text.content ="  Hello, WORLD!  ";console.log(text.content);// Outputs: hello, world!

    On compiling, it will generate the following JavaScript code.

    // Define a class with a private property and a getter/setter methodclassTextContainer{constructor(){// Define a private propertythis._content ='';}// Setter methodsetcontent(value){this._content = value.trim().toLowerCase();}// Getter methodgetcontent(){returnthis._content;}}// Create an instance of the class and set the contentconst text =newTextContainer();
    text.content ="  Hello, WORLD!  ";console.log(text.content);// Outputs: hello, world!

    Output

    hello, world!
    

    It is very important to use accessors to achieve encapsulation in TypeScript. You can also create multiple getter and setter methods in a single class.

  • Abstract Classes

    Abstraction Classes

    The abstract classes are used to achieve abstraction in TypeScript. The abstract class contains only method declaration but not implementation. We need to implement all abstract methods of the abstract class into the inherited class.

    The abstraction is a way to hide the lower-level code implementation from users and some developers. Furthermore, it is used to show only the required information about the method rather than showing the whole complex implementation of methods.

    Creating Abstract Classes

    We can use the abstract keyword to define the abstract classes or methods. The abstract classes can contain the normal and abstract types of methods. In the abstract class, we need to implement the functional or normal method and only need to declare the abstract method.

    We can inherit the abstract class using any other class, but we need to implement all abstract methods of the abstract class into the inherited class. If we dont want to implement the abstract method into the inherited class, we need to make an inherited class to abstract using the abstract keyword.

    Also, we cant create the object of the abstract class, but we can create the object of the inherited class and use the abstract class methods. The limitation of the abstract class is that we cant implement multiple inheritances using the multiple abstract classes.

    Syntax

    You can follow the syntax below to create and inherit the abstract class to other classes.

    abstract class sample {
       // define variables inside the abstract class,
       // declare the abstract methods or non-abstract method inside the abstract class
       abstract demo(string): void;
    }
    // extend sample class and implement all abstract methods of sample to demo class
    class test extends sample {
       demo(name: string): void {
    
      // code for the demo method
    } }

    Example 1

    In the example below, we have defined the abstract class containing the abstract methods. In the inherited test class, we have implemented the abstract methods of the sample class. Next, we created the object of the test class with 3 arguments and used that called the demo() and save() methods.

    abstract classsample{// define variables inside the abstract class,
       property1: string;constructor(property1: string, property2: number){this.property1 = property1;}// declare the abstract methods
       abstract demo():void;// defining the non-abstract methodssave():void{
    
      console.log("The save method of the abstract class is executed.");}}// extend sample class and implement all abstract methods of sample to demo classclasstestextendssample{
    property2: number;constructor(property1: string, property2: number){super(property1);this.property2 = property2;}demo():void{// code for the demo method
      console.log("The value of the property 3 is "+this.propert2);}}let test_obj =newtest("TutorialsPont",9999);
    test_obj.demo(); test_obj.save();

    We have hidden the implementation of the save() method from the inherited class test in the above example. We allow developers to implement the demo() method as they want but hide the other class information, such as property1, property2, and implementation of the save() method.

    Now, users understand correctly the motive to use the abstract class and how we can use it to hide the information and can reveal only the required information.

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

    var __extends =(this&&this.__extends)||(function(){varextendStatics=function(d, b){
    
      extendStatics = Object.setPrototypeOf ||({ __proto__:&#91;]}instanceofArray&amp;&amp;function(d, b){ d.__proto__ = b;})||function(d, b){for(var p in b)if(b.hasOwnProperty(p)) d&#91;p]= b&#91;p];};returnextendStatics(d, b);};returnfunction(d, b){extendStatics(d, b);function__(){this.constructor = d;}
    d.prototype = b ===null? Object.create(b):(__.prototype = b.prototype,new__());};})();var sample =/** @class */(function(){functionsample(property1, property2){this.property1 = property1;}// defining the non-abstract methods sample.prototype.save=function(){
      console.log("The save method of the abstract class is executed.");};return sample;}());// extend sample class and implement all abstract methods of sample to demo classvar test =/** @class */(function(_super){__extends(test, _super);functiontest(property1, property2){var _this =_super.call(this, property1)||this;
      _this.property2 = property2;return _this;}
    test.prototype.demo=function(){// code for the demo method
      console.log("The value of the property 3 is "+this.propert2);};return test;}(sample));var test_obj =newtest("TutorialsPont",9999);
    test_obj.demo(); test_obj.save();

    Output

    It will produce the following output

    The value of the property 3 is undefined
    The save method of the abstract class is executed.
    

    Example 2

    In the example below, the class1 is the abstract class, which contains the declaration of the abstract method name method1. The class2 only contains the definition of method2(). It extended class1 but didnt implement the abstract method named method1().

    After that, we defined class3 and inherited it via class2. Also, we have defined the method1 of class inside class3. At last, we created the object of class3 and invoked the method1() and method2().

    // define the abstract class1 containing the abstract method1
    abstract classclass1{
       abstract method1():void;}// Need to create class2 to abstract as we inherited class1 but doesn't defined abstract method1()
    abstract classclass2extendsclass1{method2():void{
    
      console.log("Inside the method 2 of class2.");}}// defining the class3 inherited by the class2classclass3extendsclass2{// Implementation of the method1 of the abstract class1method1():void{
      console.log("Implemented the abstract method name method1 of class1 inside the class3");}}// Crating the object of the class3var object =newclass3();// Invoking the method1 of class1 which is declared in the abstract class1
    object.method1();// Invoking the method2 of class2 object.method2();

    The above example shows us that if we inherit the abstract class by any class and dont want to implement the abstract method into the inherited class, we need to make the inherited class abstract.

    On compiling, above code will generate the following JavaScript code

    var __extends =(this&&this.__extends)||(function(){varextendStatics=function(d, b){
    
      extendStatics = Object.setPrototypeOf ||({ __proto__:&#91;]}instanceofArray&amp;&amp;function(d, b){ d.__proto__ = b;})||function(d, b){for(var p in b)if(b.hasOwnProperty(p)) d&#91;p]= b&#91;p];};returnextendStatics(d, b);};returnfunction(d, b){extendStatics(d, b);function__(){this.constructor = d;}
         d.prototype = b ===null? Object.create(b):(__.prototype = b.prototype,new__());};})();// define the abstract class1 containing the abstract method1var class1 =/** @class */(function(){functionclass1(){}return class1;}());// Need to create class2 to abstract as we inherited class1 but doesn't defined abstract method1()var class2 =/** @class */(function(_super){__extends(class2, _super);functionclass2(){return _super !==null&amp;&amp;_super.apply(this, arguments)||this;}
    class2.prototype.method2=function(){
      console.log("Inside the method 2 of class2.");};return class2;}(class1));// defining the class3 inherited by the class2var class3 =/** @class */(function(_super){__extends(class3, _super);functionclass3(){return _super !==null&amp;&amp;_super.apply(this, arguments)||this;}// Implementation of the method1 of the abstract class1
    class3.prototype.method1=function(){
      console.log("Implemented the abstract method name method1 of class1 inside the class3");};return class3;}(class2));// Crating the object of the class3var object =newclass3();// Invoking the method1 of class1 which is declared in the abstract class1
    object.method1();// Invoking the method2 of class2 object.method2();

    Output

    It will will produce the following output

    Implemented the abstract method name method1 of class1 inside the class3
    Inside the method 2 of class2.