<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Shubham's blog]]></title><description><![CDATA[Full stack developer | Typescript | Javascript | NextJs | Python | AWS]]></description><link>https://blog.wajeshubham.in</link><generator>RSS for Node</generator><lastBuildDate>Sun, 12 Apr 2026 23:18:04 GMT</lastBuildDate><atom:link href="https://blog.wajeshubham.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[PostgreSQL Hosting on EC2: Configuring Automated S3 Backups]]></title><description><![CDATA[The primary reason for hosting your database on EC2 is cost savings. At the time of writing this article, the most affordable/smallest RDS deployment costs approximately $20-$40 per month (depending on the usage).
In contrast, you can utilize a t2.mi...]]></description><link>https://blog.wajeshubham.in/postgresql-hosting-on-ec2-configuring-automated-s3-backups</link><guid isPermaLink="true">https://blog.wajeshubham.in/postgresql-hosting-on-ec2-configuring-automated-s3-backups</guid><category><![CDATA[PostgreSQL]]></category><category><![CDATA[AWS]]></category><category><![CDATA[ec2]]></category><category><![CDATA[S3]]></category><category><![CDATA[cronjob]]></category><dc:creator><![CDATA[Shubham Waje]]></dc:creator><pubDate>Thu, 10 Aug 2023 19:05:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1691497720669/fffae9c1-961b-4a99-beec-00b46f8e2699.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The primary reason for hosting your database on EC2 is cost savings. At the time of writing this article, the most affordable/smallest RDS deployment costs approximately $20-$40 per month (depending on the usage).</p>
<p>In contrast, you can utilize a <code>t2.micro</code> EC2 instance with 8GB of storage for approximately $8-10 USD per month. This expense can be further reduced by opting for reserved billing.</p>
<blockquote>
<p>However, if your budget allows, it's always advisable to choose RDS. It offers replication through a standby instance in a different availability zone, includes automated backups out of the box, and manages automatic failover.</p>
<p>But if you have budget constraints or are prepared to handle and manage your own Postgres instance, EC2 presents a viable option.</p>
</blockquote>
<p>An integral aspect of effective disaster recovery and preparation procedures involves <strong>automatically generating backups for production databases</strong>.</p>
<p>This article will demonstrate how to launch an EC2 instance, establish a dedicated PostgreSQL database, and implement automated backups to an S3 bucket while adhering to proper security protocols.</p>
<h1 id="heading-prerequisites">Prerequisites</h1>
<ul>
<li>An AWS Account (duh).</li>
</ul>
<h1 id="heading-launch-an-ubuntu-ec2-instance">Launch an Ubuntu EC2 instance</h1>
<p>First, navigate to the <a target="_blank" href="https://ap-south-1.console.aws.amazon.com/ec2/home?region=ap-south-1#Home:">EC2 console</a> and proceed to create an EC2 Instance using the following steps:</p>
<ol>
<li><p>Initiate the process by clicking on the <code>Launch instances</code> button.</p>
</li>
<li><p>Assign a name to your instance and opt for the <code>Ubuntu</code> OS image. Make sure to choose a Free Tier eligible AMI, which might already be pre-selected.</p>
</li>
<li><p>Opt for the <code>t2.micro</code> instance type.</p>
</li>
<li><p>Generate a new key pair and save it locally. This key will be necessary for SSH access to your instance.</p>
</li>
<li><p>Under the <code>Network settings</code> section, click the <code>Edit</code> button to adjust your security group settings according to the following instructions:</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1691403593356/b8278958-e4dd-4bfa-b001-5d905b5a03d7.png" alt class="image--center mx-auto" /></p>
<p> We need to enable <code>SSH</code> and <code>PostgreSQL</code> access for the EC2 instance, as we will be accessing the EC2 instance through a Postgres client such as <code>pgAdmin</code> or a server on port <code>5432</code>.</p>
</li>
</ol>
<blockquote>
<p>NOTE: While I am currently setting the source as <code>Anywhere (0.0.0.0/0)</code>, in a production environment, please ensure that you add your server's public IP address to the <code>Source</code> field. This step is essential to restrict access to the DB on port <code>5432</code> only to your server.</p>
</blockquote>
<ol>
<li>Keep the other settings as it is and click on <code>Launch instance</code></li>
</ol>
<h1 id="heading-install-postgresql-on-the-ec2-instance">Install PostgreSQL on the EC2 instance</h1>
<p>Now, we will install Postgres on our Ubuntu EC2 instance.</p>
<p>To do so, let's SSH into the EC2 instance. For this, we need the <code>.pem</code> file that we downloaded before launching the instance. Move that file to your <code>Desktop</code>.</p>
<p>Open your terminal on the <code>Desktop</code> and execute the following commands:</p>
<pre><code class="lang-bash">chmod 400 &lt;ssh_key_name&gt;.pem
ssh -i <span class="hljs-string">"&lt;ssh_key_name&gt;.pem"</span> ubuntu@ec1-11-111-111-11.ap-south-1.compute.amazonaws.com
<span class="hljs-comment"># Add your EC2 public IPv4 DNS in the place of `ec1-11-111-111-11.ap-south-1.compute.amazonaws.com`</span>
</code></pre>
<p>Once you are inside the Ubuntu instance run the following commands:</p>
<pre><code class="lang-bash">sudo apt update
<span class="hljs-comment"># install postgres</span>
sudo apt-get -y install postgresql
</code></pre>
<p>Once the installation is complete, the next step is to create a password for the default user <code>postgres</code></p>
<pre><code class="lang-apache"><span class="hljs-attribute">sudo</span> su postgres
<span class="hljs-comment"># this will switch to superuser with `postgres` as username</span>
<span class="hljs-attribute">postgres</span>@ip-<span class="hljs-number">111</span>-<span class="hljs-number">11</span>-<span class="hljs-number">11</span>-<span class="hljs-number">111</span>:/home/ubuntu$ psql

<span class="hljs-comment"># psql will open interactive terminal to work wil Postgresql</span>
<span class="hljs-comment"># create a password for default user</span>
<span class="hljs-attribute">postgres</span>=# ALTER USER postgres password 'mypassword';
<span class="hljs-comment"># To quit psql and exit postgres user:</span>
<span class="hljs-attribute">postgres</span>=# \q
<span class="hljs-attribute">postgres</span>@ip-<span class="hljs-number">111</span>-<span class="hljs-number">11</span>-<span class="hljs-number">11</span>-<span class="hljs-number">111</span>:/home/ubuntu$ exit
</code></pre>
<p>Please use a strong password instead of <code>mypassword</code>. Once the new password is set, you will receive a confirmation in response as A<code>"ALTER ROLE"</code> on the terminal.</p>
<p>At this point, you have successfully installed and configured an instance on an EC2 Server. Next, we need to configure a few more permissions to ensure that the PostgreSQL instance is accessible publicly from any IP address.</p>
<p>Please run the following command in your Ubuntu instance:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> /etc/postgresql/&lt;postgres_version_number&gt;/main/
<span class="hljs-comment"># for me the version number is 14 so it was cd /etc/postgresql/14/main/ for me</span>
ls
</code></pre>
<p>You will find the following files in your <code>main</code> folder</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1691406166285/9449ba36-1c35-47af-8e57-8b0c3af1f7fe.png" alt /></p>
<p>Using the Vim editor, add the following line to the <code>pg_hba.conf</code> file.</p>
<p>Run <code>sudo vim pg_hba.conf</code> and add the following line to the <code>pg_hba.conf</code>.</p>
<pre><code class="lang-bash">host       all        all              0.0.0.0/0          md5
</code></pre>
<p>Once you've added the above line, proceed to open the <code>postgresql.conf</code> file from the main folder using Vim. Locate the line <code>listen_addresses='localhost'</code>.</p>
<p>Uncomment this line as demonstrated below and substitute <code>localhost</code> with <code>*</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1691406521963/183c168c-d5f4-41a8-99c0-f03ac02f189b.png" alt class="image--center mx-auto" /></p>
<p>Now, <code>cd</code> into <code>~</code> and restart the Postgres by running the following command:</p>
<pre><code class="lang-bash">sudo service postgresql restart
</code></pre>
<p>This concludes our initial setup of the PostgreSQL server on the EC2 instance. You can now utilize the <code>public IP</code> address of the instance to establish a direct connection to the PostgreSQL server that we have just installed.</p>
<p>Next, let's proceed with the process of setting up automated backups on S3 using the <code>pg_dump</code>.</p>
<h1 id="heading-install-pgdump-on-the-ec2-instance">Install <code>pg_dump</code> on the EC2 instance</h1>
<p>Run the following command inside your EC2 instance to install <code>pg_dump</code></p>
<pre><code class="lang-bash">sudo apt install postgresql-client postgresql-client-common libpq-dev
</code></pre>
<p>Once done, check the version of the <code>pg_dump</code> which is installed</p>
<pre><code class="lang-bash">pg_dump --version
<span class="hljs-comment"># pg_dump (PostgreSQL) 12.14 (Ubuntu 12.14-0ubuntu0.20.04.1)</span>
</code></pre>
<h1 id="heading-create-a-pgpass-file">Create a <code>.pgpass</code> file</h1>
<p>The file <code>.pgpass</code> in a user's home directory or the file referenced by <code>PGPASSFILE</code> can contain passwords to be used if the connection requires a password without manually entering it.</p>
<p>The file should contain a line in the following format:</p>
<pre><code class="lang-bash">hostname:port:database:username:password
</code></pre>
<p>To do so, make sure you are in your home directory or run cd ~.</p>
<p>Then create a .pgpass file by running touch .pgpass. This will create a new file in the home directory.</p>
<p>Now, let's add the required information in the given format.</p>
<p>Run sudo vim .pgpass. This will open an empty Vim editor. Enter the following line.</p>
<pre><code class="lang-bash">&lt;ec2_instance_public_ip&gt;:5432:postgres:postgres:&lt;password_you_set&gt;
</code></pre>
<p>Once done, click <code>ESC</code> and type <code>:wq</code> to save the changes.</p>
<p>Next, set the appropriate permissions for the <code>.pgpass</code> file by executing the following command.</p>
<pre><code class="lang-bash">chmod 600 ~/.pgpass
</code></pre>
<h1 id="heading-install-aws-cli">Install AWS CLI</h1>
<p>Now, in order to enable automated backups to the S3 bucket, we need to execute certain commands that require the installation of the <code>aws cli</code> on the machine.</p>
<p>To proceed, execute the following commands:</p>
<pre><code class="lang-bash">curl <span class="hljs-string">"https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip"</span> -o <span class="hljs-string">"awscliv2.zip"</span>

sudo apt install unzip

unzip awscliv2.zip

sudo ./aws/install
</code></pre>
<h1 id="heading-setup-an-s3-bucket-for-backups">Setup an S3 bucket for backups</h1>
<p>In the <a target="_blank" href="https://s3.console.aws.amazon.com/s3/home">Amazon S3 console</a>, we will first create the bucket that will host the backup files.</p>
<p>in this case, I will go with the bucket named <code>postgres-backup-bucket</code>. Note the ARN of the bucket that is created as we will need it soon enough.</p>
<blockquote>
<p>NOTE: Make sure <strong><em>you do not</em></strong> enable public access to this bucket!</p>
</blockquote>
<h1 id="heading-create-an-iam-policy-to-control-access-to-the-s3-bucket">Create an IAM Policy to control access to the S3 bucket</h1>
<ul>
<li><p>Open the <a target="_blank" href="https://console.aws.amazon.com/iamv2/home">IAM console</a> in AWS, then under Policies click <code>Create New</code>.</p>
</li>
<li><p>In the resulting screen, click on <code>{} JSON</code> and paste the following (replacing <code>&lt;arn of S3 bucket&gt;</code> with the ARN of the bucket created in the previous step):</p>
</li>
</ul>
<pre><code class="lang-json">{
  <span class="hljs-attr">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>,
  <span class="hljs-attr">"Statement"</span>: [
    {
      <span class="hljs-attr">"Sid"</span>: <span class="hljs-string">"VisualEditor0"</span>,
      <span class="hljs-attr">"Effect"</span>: <span class="hljs-string">"Allow"</span>,
      <span class="hljs-attr">"Action"</span>: [
        <span class="hljs-string">"s3:PutObject"</span>,
        <span class="hljs-string">"s3:GetObject"</span>,
        <span class="hljs-string">"s3:ListBucket"</span>,
        <span class="hljs-string">"s3:DeleteObject"</span>
      ],
      <span class="hljs-attr">"Resource"</span>: [
        <span class="hljs-string">"&lt;arn of S3 bucket&gt;"</span>, 
        <span class="hljs-string">"&lt;arn of S3 bucket&gt;/*"</span>
    ]
    }
  ]
}
</code></pre>
<ul>
<li>Name the policy <code>GrantAccessToBackupBucket</code>.</li>
</ul>
<p>This bucket does exactly what the name suggests, it allows whichever IAM principal this policy is attached to have read/write access to the S3 bucket setup to receive the backups.</p>
<h1 id="heading-create-an-iam-role-that-is-attached-to-the-grantaccesstobackupbucket-policy">Create an IAM Role that is attached to the <code>GrantAccessToBackupBucket</code> Policy</h1>
<ul>
<li><p>Return to the <a target="_blank" href="https://console.aws.amazon.com/iamv2/home">IAM console</a>, open up the Roles page and click <code>Create Role</code>.</p>
</li>
<li><p>On the resulting screen, select <code>EC2</code> as the Service, then click Next.</p>
</li>
<li><p>On the permission screen search for the policy named <code>GrantAccessToBackupBucket</code> and attach it.</p>
</li>
<li><p>Next, we give our new IAM role a name <code>PostgresSQL-EC2-S3-CRUD-Role</code></p>
</li>
</ul>
<p>What we’ve done in this step is create an IAM role that can be attached to an EC2 instance.</p>
<p>This IAM role will enable the EC2 instance to transparently read/write to the S3 buckets for our backups without requiring us to do any configuration inside of the machine itself.</p>
<h1 id="heading-attach-the-iam-role-to-the-ec2-instance">Attach the IAM Role to the EC2 instance</h1>
<ul>
<li><p>Open the <a target="_blank" href="https://console.aws.amazon.com/ec2/v2/home">EC2 console</a>, identify the Ec2 instance hosting the database, click on it and then under <code>Actions -&gt; Security</code>, select <code>Modify IAM role</code>.</p>
</li>
<li><p>On the resulting page search for and select the IAM role named,<br />  <code>PostgresSQL-EC2-S3-CRUD-Role</code>.</p>
</li>
<li><p>Click Save.</p>
</li>
</ul>
<p>At this point, we’ve now set up our EC2 instance to have read/write access to the S3 bucket being used for backups.</p>
<blockquote>
<p>Note: up until this point the instructions I’ve laid out are pretty generic and have nothing to do with database backups, you can follow these steps if you are building an app and want your backend code to be able to read/write to an S3 bucket.</p>
</blockquote>
<h1 id="heading-create-a-backup-script-on-the-ec2-machine">Create a backup script on the EC2 machine</h1>
<ul>
<li><p>SSH into your EC2 machine.</p>
</li>
<li><p>Create a new file named <code>backup-db.sh</code></p>
</li>
<li><p>Grant execute permissions on the script by executing: <code>chmod +x backup-db.sh</code></p>
</li>
<li><p>Open up the file and paste the following:</p>
<pre><code class="lang-bash">  <span class="hljs-comment"># Create the backup file</span>
  TIME=$(date --utc <span class="hljs-string">"+%Y%m%d_%H%M%SZ"</span>)

  <span class="hljs-comment"># Use the timestamp to construct a descriptive file name</span>
  BACKUP_FILE=<span class="hljs-string">"backup-pg-<span class="hljs-variable">${TIME}</span>.pgdump"</span>
  DATABASE_NAME=<span class="hljs-string">"postgres"</span>
  HOST=<span class="hljs-string">"&lt;ec2_public_ip&gt;"</span>
  PORT=5432
  USERNAME=<span class="hljs-string">"postgres"</span>
  pg_dump <span class="hljs-variable">$DATABASE_NAME</span> -h <span class="hljs-variable">$HOST</span> -p <span class="hljs-variable">$PORT</span> -U <span class="hljs-variable">$USERNAME</span> -w --format=custom &gt; <span class="hljs-variable">$BACKUP_FILE</span>

  <span class="hljs-comment"># -h host</span>
  <span class="hljs-comment"># -p port</span>
  <span class="hljs-comment"># -U username</span>
  <span class="hljs-comment"># -w this avoids a password prompt and refers .pgpass file for password</span>

  <span class="hljs-comment"># Second, copy file to AWS S3</span>
  S3_BUCKET=s3://&lt;backup_bucket_bame&gt;
  S3_TARGET=<span class="hljs-variable">$S3_BUCKET</span>/<span class="hljs-variable">$BACKUP_FILE</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-string">"Copying <span class="hljs-variable">$BACKUP_FILE</span> to <span class="hljs-variable">$S3_TARGET</span>"</span>
  aws s3 cp <span class="hljs-variable">$BACKUP_FILE</span> <span class="hljs-variable">$S3_TARGET</span>

  <span class="hljs-comment"># verify the backup was uploaded correctly</span>
  <span class="hljs-built_in">echo</span> <span class="hljs-string">"Backup completed for <span class="hljs-variable">$DATABASE_NAME</span>"</span>
  BACKUP_RESULT=$(aws s3 ls <span class="hljs-variable">$S3_BUCKET</span> | tail -n 1)
  <span class="hljs-built_in">echo</span> <span class="hljs-string">"Latest S3 backup: <span class="hljs-variable">$BACKUP_RESULT</span>"</span>

  <span class="hljs-comment"># clean up and delete the local backup file</span>
  rm <span class="hljs-variable">$BACKUP_FILE</span>
</code></pre>
</li>
</ul>
<p>At this point, manually execute the <code>backup-db.sh</code> file and watch the console log output.</p>
<p>Run <code>./backup-db.sh</code> and check the console.</p>
<p>It should be pretty clear whether or not the backup and upload succeeded or not. If the process is successful, proceed to verify whether your S3 bucket contains a database snapshot generated by the <code>pg_dump</code> command.</p>
<h1 id="heading-automate-the-execution-of-the-backup-with-cronjob">Automate the execution of the backup with cronjob</h1>
<ul>
<li><p>Open the crontab by typing <code>crontab -e</code> in your EC2 instance</p>
</li>
<li><p>In the resulting editor window, we add the following line:</p>
</li>
</ul>
<pre><code class="lang-bash">0 0  * ~/backup-db.sh &amp;&gt;&gt; ~/backup-db.log
</code></pre>
<p>Note the above cron expression runs the backup script once per day at midnight.</p>
<blockquote>
<p>NOTE: If you want to run this at different frequencies then use this handy <a target="_blank" href="https://crontab.guru/">cron expression generator</a> which will help you in generating the right cron syntax to match your desired frequency.</p>
</blockquote>
<h1 id="heading-test-your-backup">Test your backup!</h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1691474378086/3cbf559c-15d1-4a5e-b0da-5ffbd2406bea.png" alt class="image--center mx-auto" /></p>
<p>In the image above, you can observe my automated backup, which was generated at 5:30 in the morning. Therefore, congratulations are in order as you now possess a secure and dependable automated backup mechanism.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<ul>
<li><p>In conclusion, this blog has explored the cost-effective approach of hosting a PostgreSQL database on an EC2 instance, shedding light on the practical steps to implement automated daily backups seamlessly. By harnessing the power of EC2's hosting capabilities and integrating automated backups, you've unlocked a robust solution that ensures the safety and availability of your valuable data.</p>
</li>
<li><p>Looking ahead, I'm excited to share a forthcoming article that will delve into the intricate process of restoring data from an S3 backup file generated by the automated backup mechanism. Stay tuned for this informative guide, where we'll navigate through the steps to seamlessly retrieve and reinstate your data, ensuring business continuity and data integrity.</p>
</li>
</ul>
<p>Make sure to subscribe to our newsletter at <a target="_blank" href="https://blog.wajeshubham.in/">https://blog.wajeshubham.in/</a> and never miss any upcoming articles.</p>
<p>I hope this post will help you in your journey. Keep learning!</p>
<p>My <a target="_blank" href="https://wajeshubham.in">Website</a>, connect with me on <a target="_blank" href="https://www.linkedin.com/in/shubham-waje/">LinkedIn</a> and <a target="_blank" href="https://github.com/wajeshubham">GitHub</a></p>
]]></content:encoded></item><item><title><![CDATA[Understand TypeScript Generics]]></title><description><![CDATA[It is one of the most critical things in software development to create components that are not only well-defined and consistent but also reusable. Components that are capable of working on the data of today, as well as the data of tomorrow, will giv...]]></description><link>https://blog.wajeshubham.in/understand-typescript-generics</link><guid isPermaLink="true">https://blog.wajeshubham.in/understand-typescript-generics</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[generics]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Shubham Waje]]></dc:creator><pubDate>Thu, 09 Mar 2023 05:39:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1678340267871/10ad72c8-d284-42d9-b0ad-e79cc5a4fa80.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>It is one of the most critical things in software development to create components that are not only well-defined and consistent but also reusable. Components that are capable of working on the data of today, as well as the data of tomorrow, will give you the most flexible capabilities for building up large software systems.</p>
<p>The purpose of this article is to demonstrate how TypeScript generics can be applied to functions, types, classes, and interfaces to make them dynamic and reusable.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647755113846/VPnWbZHjO.png" alt="Generics in Typescript.png" /></p>
<h2 id="heading-what-exactly-is-generic">WHAT EXACTLY IS GENERIC?</h2>
<blockquote>
<p><strong>In languages like TypeScript, C#, and Java, one of the main tools in the toolbox for creating reusable components is generics, that is, being able to create a component that can work over a variety of types rather than a single one. This allows users to consume these components and use their types.</strong></p>
<p><strong>Generics is a tool in TypeScript that allows users to create reusable structures by passing types as parameters to functions, types, classes, and interfaces. This structure can work with a variety of data types rather than just one. It ensures long-term scalability as well as flexibility for the program.</strong></p>
</blockquote>
<h2 id="heading-setup-a-project">SETUP A PROJECT:</h2>
<blockquote>
<p>To run the following code snippets, you need to have <code>typescript</code> installed globally. If you don't have <code>typescript</code> installed, run <code>npm install -g typescript</code> in your terminal and check out my blog on <a target="_blank" href="https://blog.wajeshubham.in/introduction-to-typescript#heading-lets-set-up-a-project">Introduction to TypeScript</a> to set up a typescript project required for this article.</p>
</blockquote>
<h2 id="heading-introduction-to-generics">INTRODUCTION TO GENERICS:</h2>
<p>Whenever you create a generic structure, you must use <code>&lt;&gt;</code> to wrap the parameters that the generic structure accepts.</p>
<p>The following is the syntax for creating a generic structure:</p>
<h3 id="heading-syntax">SYNTAX:</h3>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">example</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params">arg: T</span>): <span class="hljs-title">T</span> </span>{
  <span class="hljs-keyword">return</span> arg;
}
</code></pre>
<p>For the moment, we have declared a generic function (we will delve into generic functions in upcoming topics in this article).</p>
<p>To the <code>example</code> function, we have added the type variable <code>T</code>. The <code>T</code> allows us to capture the type that the user provides as an argument (e.g. <code>number</code>) for later use. (<code>T</code> stands for <code>Type</code>, and is commonly used as the first type variable name when defining generics, but it can be replaced with any valid name.)</p>
<p>This function's return type and argument type are dependent on what we pass in while calling it.</p>
<p>Check out the following code to see how we can pass generic-type arguments:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> returnedValue = example&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-string">'hello'</span>);
</code></pre>
<p><code>string</code> was passed as a <strong>TYPE</strong> argument to the generic <code>example</code> function.</p>
<p>Let's hover over the <code>returnedValue</code> variable and look at the return type:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647974388706/E680AVFvJ.png" alt="image.png" /></p>
<p>The return type is a <code>string</code>, which we passed as a type argument.</p>
<h3 id="heading-adds-strict-type-checking">ADDS STRICT TYPE CHECKING:</h3>
<p>Generics have strict type-checking. Our code above passes a <code>string</code> as a <strong>type argument</strong>, so we must pass a <code>string</code> in the <strong>function argument</strong> as well.</p>
<p>In the case of any other type, we will encounter the following compilation error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647756640928/Lq-jZTOeI.png" alt="image.png" /></p>
<p>This is the beauty of generics in typescript because they are dynamic, yet strictly typed at the same time.</p>
<h3 id="heading-accepts-any-valid-type">ACCEPTS ANY VALID TYPE:</h3>
<p>As opposed to passing <code>string</code> as a type argument in the above example, we can also pass any valid type or interface as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Person {
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">example</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params">arg: T</span>): <span class="hljs-title">T</span> </span>{
  <span class="hljs-keyword">return</span> arg;
}

<span class="hljs-comment">// return type will be Person</span>
<span class="hljs-keyword">const</span> returnedValue = example&lt;Person&gt;({
  name: <span class="hljs-string">"Max"</span>,
  age: <span class="hljs-number">30</span>,
});
</code></pre>
<p>As you can see, we have a <code>Person</code> interface which is a valid type in TypeScript.</p>
<p>It is passed as a type argument to the <code>example</code> function, meaning the function argument must be of type <code>Person</code>.</p>
<p>If we attempt to do anything outside the rules, we will get a compilation error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647756956019/6MY4l6T9U.png" alt="image.png" /></p>
<h2 id="heading-built-in-generics">BUILT-IN GENERICS:</h2>
<p>In addition to creating our own generics, TypeScript has some built-in generics that can be used.</p>
<p>The following are some generics that TypeScript offers:</p>
<h3 id="heading-array-type"><code>Array&lt;T&gt;</code> TYPE:</h3>
<p>My previous articles have discussed this <code>Array</code> type and referred to it as a generic type.</p>
<p>It is probably one of the most commonly used generics in TypeScript.</p>
<p>Here's how to declare a variable's type using the <code>Array</code> keyword:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> names: <span class="hljs-built_in">Array</span>&lt;<span class="hljs-built_in">string</span>&gt; = [<span class="hljs-string">"John"</span>, <span class="hljs-string">"Jane"</span>, <span class="hljs-string">"Mary"</span>];
</code></pre>
<p>Here, we have a variable called <code>names</code>, and we have declared it as an <code>Array&lt;string&gt;</code> <em>(array of strings)</em>. In other words, it's the equivalent of <code>string[]</code>, which we have used in the past.</p>
<p>What happens if we don't pass <code>string</code> as a type argument to the <code>Array</code> type?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647757617275/pEf1kcnst.png" alt="image.png" /></p>
<p>It says <code>Generic type 'Array&lt;T&gt;' requires 1 type argument(s).</code> This means we need to pass a type argument to the <code>Array</code> keyword.</p>
<p>What happens if we pass a different type of value in an array of type <code>Array&lt;string&gt;</code>?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647757741321/FchqiHdW_.png" alt="image.png" /></p>
<p>Similar to our <code>example</code> function, this compiles with an error if we pass a different type value in a generic structure.</p>
<h3 id="heading-promise-type"><code>Promise&lt;T&gt;</code> TYPE:</h3>
<p><code>Promise</code> is another built-in generic type. It expects only one <code>type argument</code>.</p>
<blockquote>
<p>If you want to learn more about promises, check out my detailed article on <a target="_blank" href="https://blog.learncodeonline.in/promises-in-javascript">Promises in JavaScript</a>.</p>
</blockquote>
<p>Let's take an example to better understand the <code>Promise</code> type. Look at the following code.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> _promise = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
    resolve(<span class="hljs-string">"Success!"</span>);
  }, <span class="hljs-number">2000</span>);
});

_promise.then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(data);
});
</code></pre>
<p>The above code creates a <code>_promise</code> variable, which is a <code>Promise</code> that returns a <code>string</code> when it is resolved.</p>
<p>Our promise is then triggered with a <code>.then()</code> block and the resolved value is captured in the <code>data</code> variable.</p>
<p>Let's hover over the <code>_promise</code> variable and see what type is inferred:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647758682887/zuuJHmd6c.png" alt="image.png" /></p>
<p>The type shown is <code>Promise&lt;unknown&gt;</code>, which is not beneficial since we know that it will resolve to a <code>string</code>.</p>
<p>Therefore, to make it happen, we can use <code>Promise</code> type and pass <code>string</code> as a type argument to it as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> _promise: <span class="hljs-built_in">Promise</span>&lt;<span class="hljs-built_in">string</span>&gt; = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
    resolve(<span class="hljs-string">"Success!"</span>);
  }, <span class="hljs-number">2000</span>);
});

_promise.then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
  <span class="hljs-comment">// type of data is string</span>
  <span class="hljs-built_in">console</span>.log(data);
});
</code></pre>
<p>Now, if we add <code>.</code> in front of <code>data</code> in the <code>.then()</code> block, we will get autosuggestions of all string methods available:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647758840510/Y6MKJGtCD.png" alt="image.png" /></p>
<blockquote>
<p>We will see how we can use <code>Promise</code> and <code>Axios</code> to write scalable API functions in the next part of this article.</p>
</blockquote>
<h3 id="heading-readonly-type"><code>Readonly&lt;T&gt;</code> TYPE:</h3>
<p><code>Readonly</code> is a generic, built-in type that allows us to throw errors whenever a method that alters or mutates the original structure is used.</p>
<p>It constructs a type with all properties of <code>T</code> set to <code>readonly</code>. See for yourself:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> x: Readonly&lt;<span class="hljs-built_in">number</span>[]&gt; = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];

x.push(<span class="hljs-number">4</span>); <span class="hljs-comment">// error</span>
x.length = <span class="hljs-number">0</span>; <span class="hljs-comment">// error</span>
x[<span class="hljs-number">0</span>] = <span class="hljs-number">12</span>; <span class="hljs-comment">// error</span>

x.map(<span class="hljs-function">(<span class="hljs-params">v</span>) =&gt;</span> v); <span class="hljs-comment">// without error</span>
x.filter(<span class="hljs-function">(<span class="hljs-params">v</span>) =&gt;</span> v &gt; <span class="hljs-number">1</span>); <span class="hljs-comment">// without error</span>
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> y: Readonly&lt;{
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
}&gt; = {
  name: <span class="hljs-string">"John"</span>,
  age: <span class="hljs-number">30</span>,
};

y.age = <span class="hljs-number">20</span>; <span class="hljs-comment">// error!</span>
y.name = <span class="hljs-string">"John"</span>; <span class="hljs-comment">// error!</span>
</code></pre>
<p>When you want an array/object that never changes, this is useful.</p>
<h3 id="heading-partial-type"><code>Partial&lt;T&gt;</code> TYPE:</h3>
<p>It constructs a type with all properties of <code>T</code> set to optional.</p>
<p>Take a look at the following example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Course {
  title: <span class="hljs-built_in">string</span>;
  price: <span class="hljs-built_in">number</span>;
  description: <span class="hljs-built_in">string</span>;
  rating: <span class="hljs-built_in">number</span>;
}

<span class="hljs-comment">// same as { title?: string; price?: number; description?: string; rating?: number; }</span>
<span class="hljs-keyword">let</span> course: Partial&lt;Course&gt; = {};
</code></pre>
<p><code>Partial</code> will make all the properties of the <code>Course</code> interface optional.</p>
<h3 id="heading-nonnullable-type"><code>NonNullable&lt;T&gt;</code> TYPE:</h3>
<p><code>NonNullable&lt;T&gt;</code> prevents you from passing <code>null</code> or <code>undefined</code> to your structure. This complements the <code>strictNullChecks</code> compiler flag in the <code>tsconfig.json</code> file, so make sure you activate it <em>(ignore it if you have</em> <code>strict</code> flag set to <code>true</code>):</p>
<p>Let's use <code>NonNullable</code> in our <code>example</code> function code.</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">example</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params">arg: T</span>): <span class="hljs-title">T</span> </span>{
  <span class="hljs-keyword">return</span> arg;
}

<span class="hljs-keyword">let</span> a = example&lt;<span class="hljs-built_in">string</span> | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>); <span class="hljs-comment">// runs without error</span>
</code></pre>
<p>Now the type argument is a <code>string | null</code> union type. The code above executes without error.</p>
<p>We'll see what happens with <code>NonNullable</code>:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">example</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params">arg: NonNullable&lt;T&gt;</span>): <span class="hljs-title">T</span> </span>{
  <span class="hljs-keyword">return</span> arg;
}

<span class="hljs-keyword">let</span> a = example&lt;<span class="hljs-built_in">string</span> | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>); <span class="hljs-comment">// throws error</span>
</code></pre>
<p>Even though a <code>null</code> could be passed to our generic example function as a function argument, the <code>NonNullable</code> type internally discards it.</p>
<h2 id="heading-generic-functions">GENERIC FUNCTIONS:</h2>
<p>We looked at how we can accept type as a parameter in the first topic of this article by using the <code>example</code> function.</p>
<p>Here are some more complex examples of generic functions.</p>
<h3 id="heading-function-to-merge-two-objects">FUNCTION TO MERGE TWO OBJECTS:</h3>
<p>Suppose we want to create a merge function that takes two arguments, both are objects and returns the merged object.</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mergeObjects</span>(<span class="hljs-params">obj1: <span class="hljs-built_in">object</span>, obj2: <span class="hljs-built_in">object</span></span>) </span>{
  <span class="hljs-keyword">return</span> { ...obj1, ...obj2 };
}

<span class="hljs-keyword">const</span> mergedObj = mergeObjects({ name: <span class="hljs-string">"Max"</span> }, { age: <span class="hljs-number">30</span> });
</code></pre>
<p>We have the <code>mergeObjects</code> function here, which merges the <code>obj1</code> and <code>obj2</code> of type <code>object</code> and returns the merged <code>object</code>.</p>
<p>Then we call the function with some arguments and store the returned data in the <code>mergedObj</code> variable.</p>
<p>Let's hover over the <code>mergedObj</code> variable and see what the inferred type is.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647761979974/yqi60nKLx.png" alt="image.png" /></p>
<p>We have <code>{}</code> (an object), which is not beneficial, because when we access the <code>age</code> property on the <code>mergedObj</code> variable, we will receive a compilation error as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647762142397/zKKAK0rVX.png" alt="image.png" /></p>
<p>But as a developer, we know that if we merge <code>{ name: "Max" }</code> and <code>{ age: 30 }</code>, we should get <code>{ name: "Max", age: 30 }</code> in return.</p>
<p>To accomplish this, let's convert this function into a generic function.</p>
<h3 id="heading-convert-it-to-a-generic-function">CONVERT IT TO A GENERIC FUNCTION:</h3>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mergeObjects</span>&lt;<span class="hljs-title">T</span>, <span class="hljs-title">U</span>&gt;(<span class="hljs-params">obj1: T, obj2: U</span>) </span>{
  <span class="hljs-keyword">return</span> { ...obj1, ...obj2 };
}

<span class="hljs-keyword">const</span> mergedObj = mergeObjects({ name: <span class="hljs-string">"Max"</span> }, { age: <span class="hljs-number">30</span> });
</code></pre>
<p>The <code>mergeObjects</code> method accepts two <code>type parameters</code> <code>T</code> and <code>U</code>. These type parameters are assigned to <code>obj1</code> and <code>obj2</code> respectively.</p>
<p>Now, if we call the <code>mergeObjects</code> function with the same function arguments. <code>T</code> and <code>U</code> will automatically become the type inferred from the passed arguments. <em>(We don't have to specify the type for</em> <code>T</code> and <code>U</code>, TypeScript automatically manages that for us)</p>
<p>Thus, <code>T</code> will be assigned as <code>{name: string}</code> and <code>U</code> will be assigned as <code>{age: number}</code>.</p>
<p>If we hover over the <code>mergedObj</code> variable we will see the following inferred type:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647762392138/HXEhJEI39.png" alt="image.png" /></p>
<p>The <code>mergedObj</code> variable got inferred as an <code>intersection type</code> including <code>{name: string}</code> and <code>{age: number}</code>. <em>(To learn more about intersection types, click</em> <a target="_blank" href="https://blog.wajeshubham.in/advance-typescript#heading-intersection-type"><em>here</em></a><em>)</em></p>
<p>Now if we try to access the <code>age</code> property on the <code>mergedObj</code> variable, we will get autosuggestions from the IDE and will not get compilation errors, as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647762614466/OCUuwudBr.png" alt="image.png" /></p>
<h3 id="heading-it-is-dynamic">IT IS DYNAMIC:</h3>
<p>A generic function is useful because now you can pass literally any key in the object, and the function will automatically detect which keys are available in the merged objects.</p>
<p>Here's an example containing more keys in one of the arguments of the <code>mergeObjects</code> function.</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mergeObjects</span>&lt;<span class="hljs-title">T</span>, <span class="hljs-title">U</span>&gt;(<span class="hljs-params">obj1: T, obj2: U</span>) </span>{
  <span class="hljs-keyword">return</span> { ...obj1, ...obj2 };
}

<span class="hljs-keyword">const</span> mergedObj = mergeObjects(
  { name: <span class="hljs-string">"Max"</span>, skills: [<span class="hljs-string">"typescript"</span>, <span class="hljs-string">"javascript"</span>], salary:<span class="hljs-string">"5000"</span> },
  { age: <span class="hljs-number">30</span> }
);
</code></pre>
<p>Let's see what the autosuggestions have to offer:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647762957128/n0AQL1kZ_.png" alt="image.png" /></p>
<p>Generic functions are great for this.</p>
<h2 id="heading-generic-constraints">GENERIC CONSTRAINTS:</h2>
<p>There is a problem with the above <code>mergeObjects</code> function. The compiler will not throw an error if we pass any type of value as an argument.</p>
<p>Look at the following image:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647763579228/shLVAZC5M.png" alt="image.png" /></p>
<p>This is a problem because only and only <code>objects</code> should be allowed as arguments to the <code>mergeObjects</code> function to avoid unexpected results.</p>
<p>To do so, we can use <strong>generic constraints</strong> to add more type-checking.</p>
<h3 id="heading-extends-keyword"><code>extends</code> KEYWORD:</h3>
<p>So our logic is that we want to make <code>mergeObjects</code> generic, but we can only accept arguments of type <code>object</code>.</p>
<p>To accomplish that, we can do the following:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mergeObjects</span>&lt;<span class="hljs-title">T</span> <span class="hljs-title">extends</span> <span class="hljs-title">object</span>, <span class="hljs-title">U</span> <span class="hljs-title">extends</span> <span class="hljs-title">object</span>&gt;(<span class="hljs-params">obj1: T, obj2: U</span>) </span>{
  <span class="hljs-keyword">return</span> { ...obj1, ...obj2 };
}

<span class="hljs-keyword">const</span> mergedObj = mergeObjects({ name: <span class="hljs-string">"Max"</span>, age: <span class="hljs-number">20</span> }, <span class="hljs-number">30</span>); <span class="hljs-comment">// throws error</span>

<span class="hljs-built_in">console</span>.log(mergedObj);
</code></pre>
<p>By using the <code>extends</code> keyword, we tell TypeScript that the <code>mergeObjects</code> function can accept any type of argument, but it must be of type <code>object</code>.</p>
<p>Now if we try to pass <code>number</code> as an argument, we get a compilation error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647765638723/LfNS357TN.png" alt="image.png" /></p>
<h3 id="heading-keyof-keyword"><code>keyof</code> KEYWORD:</h3>
<p>Let's use an example to understand the use case for the <code>keyof</code> keyword:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getValueFromObj</span>&lt;<span class="hljs-title">T</span> <span class="hljs-title">extends</span> <span class="hljs-title">object</span>, <span class="hljs-title">U</span>&gt;(<span class="hljs-params">obj: T, key: U</span>) </span>{
  <span class="hljs-keyword">return</span> obj[key];
}

getValueFromObj({ name: <span class="hljs-string">"John"</span> }, <span class="hljs-string">"name"</span>);
</code></pre>
<p>In the above function, we are accepting two parameters <code>obj</code> and <code>key</code>. <code>obj</code> is of <code>T</code> type which extends the <code>object</code> type, and <code>key</code> is of <code>U</code> type. Next, we are returning the value from the <code>obj</code> object by using the <code>key</code> parameter.</p>
<p>There is a compilation error here since TypeScript has no idea whether that <code>key</code> is present in the <code>obj</code> or not.</p>
<p>For the above code to be valid, we can use the <code>keyof</code> keyword to only accept the <code>key</code> which exists inside an <code>obj</code> object.</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getValueFromObj</span>&lt;<span class="hljs-title">T</span> <span class="hljs-title">extends</span> <span class="hljs-title">object</span>, <span class="hljs-title">U</span> <span class="hljs-title">extends</span> <span class="hljs-title">keyof</span> <span class="hljs-title">T</span>&gt;(<span class="hljs-params">obj: T, key: U</span>) </span>{
  <span class="hljs-keyword">return</span> obj[key];
}

getValueFromObj({ name: <span class="hljs-string">"John"</span> }, <span class="hljs-string">"name"</span>);
</code></pre>
<p>We are adding code here to make <code>U</code> only accept keys that are contained within the <code>obj</code> object.</p>
<p>Passing a key that does not exist in a passed object will cause a compilation error as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647767270370/qK9TlAtl6.png" alt="image.png" /></p>
<h2 id="heading-generic-classes">GENERIC CLASSES:</h2>
<p>Generic classes have a generic type parameter list in angle brackets (&lt;&gt;) following the name of the class as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> ClassName&lt;T&gt; {}
</code></pre>
<h3 id="heading-mystorage-class-example"><code>MyStorage</code> CLASS EXAMPLE:</h3>
<p>Let's create a class that stores an array of data and performs operations on that data.</p>
<p>Check out the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> MyStorage {
  <span class="hljs-keyword">private</span> storedData: <span class="hljs-built_in">any</span>[] = [];

  <span class="hljs-keyword">public</span> setItem(value: <span class="hljs-built_in">any</span>) {
    <span class="hljs-built_in">this</span>.storedData.push(value);
  }

  <span class="hljs-keyword">public</span> removeItem(index: <span class="hljs-built_in">number</span>) {
    <span class="hljs-built_in">this</span>.storedData.splice(index, <span class="hljs-number">1</span>);
  }

  <span class="hljs-keyword">public</span> getItems() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.storedData;
  }
}
</code></pre>
<p>In the previous blogs, we learned that we should never use <code>any</code> keyword unless there are no other options, and no type definitions are available for the piece of code you're working on.</p>
<p>The above <code>MyStorage</code> class can be converted to a generic class to make it more strongly typed and dynamic.</p>
<h3 id="heading-make-mystorage-class-generic">MAKE <code>MyStorage</code> CLASS GENERIC:</h3>
<p>Check out the following code.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> MyStorage&lt;T&gt; {
  <span class="hljs-keyword">private</span> storedData: T[] = [];

  <span class="hljs-keyword">public</span> setItem(value: T) {
    <span class="hljs-built_in">this</span>.storedData.push(value);
  }

  <span class="hljs-keyword">public</span> removeItem(index: <span class="hljs-built_in">number</span>) {
    <span class="hljs-built_in">this</span>.storedData.splice(index, <span class="hljs-number">1</span>);
  }

  <span class="hljs-keyword">public</span> getItems() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.storedData;
  }
}
</code></pre>
<p>We have a <code>MyStorage</code> class that is generic, accepting a type parameter <code>T</code>, and has <code>storedData</code> property that is of type <code>T[]</code> (an array of the type T).</p>
<p>Additionally, it has <code>setItem</code>, <code>removeItem</code>, and <code>getItems</code> methods.</p>
<p>Let's create an instance of it.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> MyStorage&lt;T&gt; {
  <span class="hljs-keyword">private</span> storedData: T[] = [];

  <span class="hljs-keyword">public</span> setItem(value: T) {
    <span class="hljs-built_in">this</span>.storedData.push(value);
  }

  <span class="hljs-keyword">public</span> removeItem(index: <span class="hljs-built_in">number</span>) {
    <span class="hljs-built_in">this</span>.storedData.splice(index, <span class="hljs-number">1</span>);
  }

  <span class="hljs-keyword">public</span> getItems() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.storedData;
  }
}

<span class="hljs-keyword">const</span> stringStorage = <span class="hljs-keyword">new</span> MyStorage&lt;<span class="hljs-built_in">string</span>&gt;();
</code></pre>
<p>For <code>stringStorage</code>, the <code>T</code> will be a <code>string</code>. Therefore, the <code>storedData</code> property of the <code>MyStorage</code> class will be of type <code>string[]</code>.</p>
<p>Let's add some items to our storage now.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> stringStorage = <span class="hljs-keyword">new</span> MyStorage&lt;<span class="hljs-built_in">string</span>&gt;();

stringStorage.setItem(<span class="hljs-string">"Hello"</span>);
stringStorage.setItem(<span class="hljs-string">"World"</span>);
stringStorage.removeItem(<span class="hljs-number">1</span>);
<span class="hljs-built_in">console</span>.log(stringStorage.getItems()); <span class="hljs-comment">// ["Hello"]</span>
</code></pre>
<p>Everything works fine!</p>
<h3 id="heading-ide-support">IDE SUPPORT:</h3>
<p>Similarly, we can create storage for complex types using the <code>MyStorage</code> class.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Employee {
    name: <span class="hljs-built_in">string</span>;
    age: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">const</span> employeeStorage = <span class="hljs-keyword">new</span> MyStorage&lt;Employee&gt;();

employeeStorage.setItem({ name: <span class="hljs-string">'John'</span>, age: <span class="hljs-number">30</span> });
employeeStorage.setItem({ name: <span class="hljs-string">'Alex'</span>, age: <span class="hljs-number">29</span> });

<span class="hljs-keyword">let</span> employees = employeeStorage.getItems();
<span class="hljs-built_in">console</span>.log(employees); <span class="hljs-comment">// prints [{name: 'John', age: 30}, {name: 'Alex', age: 29}]</span>
</code></pre>
<p>If we try to operate on the <code>employees</code> variable, we will receive the following autosuggestions from the IDE:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647769984836/iwOHr3lI9.png" alt="image.png" /></p>
<h3 id="heading-strictly-typed-and-flexible">STRICTLY TYPED AND FLEXIBLE:</h3>
<p>Once you specify what type of data the <code>MyStorage</code> class preserves, you cannot pass different types of arguments to its methods. If you do so, you will receive an error such as the following:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647770026817/wdX6kaO3D.png" alt="image.png" /></p>
<p>This is the beauty of a generic class. It is flexible and strictly typed at the same time.</p>
<h2 id="heading-generic-interfaces">GENERIC INTERFACES:</h2>
<p>We can implement generic interfaces in a similar way to generic classes. It almost works the same way.</p>
<p>To understand the syntax, let's look at an example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> KeyPair&lt;T, U&gt; {
  key: T;
  value: U;
}

<span class="hljs-keyword">let</span> kp1: KeyPair&lt;<span class="hljs-built_in">number</span>, <span class="hljs-built_in">string</span>&gt; = { key:<span class="hljs-number">1</span>, value:<span class="hljs-string">"Steve"</span> }; 
<span class="hljs-keyword">let</span> kp2: KeyPair&lt;<span class="hljs-built_in">number</span>, <span class="hljs-built_in">number</span>&gt; = { key:<span class="hljs-number">1</span>, value:<span class="hljs-number">12345</span> };
</code></pre>
<p>As you can see in the above example, by using the generic interface as type, we can specify the data type of <code>key</code> and <code>value</code>.</p>
<p>In a similar way to classes, we can pass dynamic types to the interface. So, let's see how we can use generics in a real-world project to make the most of it.</p>
<h2 id="heading-generics-with-axios-and-react">GENERICS WITH <code>Axios</code> AND <code>React</code>:</h2>
<p><code>Axios</code> is a simple promise-based HTTP client for the browser and node.js. It provides a simple-to-use library in a small package with a very extensible interface.</p>
<p>Most commonly, it is used when working with <code>React</code> applications. Let's see how generics can be used to make the most of API calls.</p>
<h3 id="heading-setup-a-react-and-typescript-project">SETUP A <code>React</code> AND <code>TypeScript</code> PROJECT:</h3>
<p>Run the following command in your terminal to set up a React TypeScript project:</p>
<pre><code class="lang-bash">npx create-react-app react-axios-typescript --template typescript --use-npm
</code></pre>
<ul>
<li><p>By using the <code>--template typescript</code> flag, a react project with preinstalled <code>typescript</code> and <code>tsconfig.json</code> configuration will be generated.</p>
</li>
<li><p>The <code>--use-npm</code> flag is optional. If you're using <code>yarn</code> and <code>npm</code> at the same time. And you want to tell <code>create-react-app</code> to use <code>npm</code> instead of <code>yarn</code> to generate the project.</p>
</li>
</ul>
<p>Open the generated project in VS Code.</p>
<h3 id="heading-install-andamp-configure-axios">INSTALL &amp; CONFIGURE <code>axios</code>:</h3>
<p>Use the following command to install <code>axios</code> <em>(because</em> <code>axios</code> comes with built-in type declarations, so we don't have to install <code>@types/axios</code> separately)</p>
<pre><code class="lang-bash">npm install axios
</code></pre>
<p>Now, create the <code>api/index.ts</code> file inside the <code>src</code> folder. The folder structure should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647849216643/MrHpMcvPX.png" alt="image.png" /></p>
<p>Let's configure our <code>axios</code> client and create the <code>ApiService</code> class to write API calls.</p>
<p>In your <code>api/index.ts</code> file, add the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;

<span class="hljs-keyword">const</span> axiosClient = axios.create({
  <span class="hljs-comment">// url which is prefixed to all the requests made using this instance</span>
  baseURL: <span class="hljs-string">"https://jsonware.com/api/v1/json"</span>
});

<span class="hljs-keyword">class</span> ApiService {
  <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> getCourseById(id: <span class="hljs-built_in">string</span>) {
    <span class="hljs-keyword">return</span> axiosClient.get(<span class="hljs-string">`/<span class="hljs-subst">${id}</span>`</span>);
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ApiService;
</code></pre>
<p>In the code above, we have created an <code>axios</code> instance <code>axiosClient</code> with <code>baseURL</code> <em>(</em><code>baseURL</code> is the URL that will get prefixed to all requests sent via <code>axiosClient</code>. Whenever building a large-scale application, this is a good practice to create multiple instances).</p>
<p>Furthermore, we created a class <code>ApiService</code> which will hold all the <code>static</code> methods for API calls. <em>(To learn more about static methods/properties in typescript, click</em> <a target="_blank" href="https://blog.wajeshubham.in/classes-in-typescript#heading-static-properties-andamp-methods"><em>here</em></a><em>)</em></p>
<p><code>getCourseById</code> is an asynchronous method that uses <code>axiosClient</code> for an API call.</p>
<p>As you hover your cursor over the <code>getCourseById</code> method, you will see its return type is as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647850004271/kpxmsyB-l.png" alt="image.png" /></p>
<p>It is <code>Promise&lt;AxiosResponse&lt;any, any&gt;&gt;</code>.</p>
<p>Now, let's break this!</p>
<p>I have explained that the <code>Promise</code> is a generic type in one of the previous topics in this article.</p>
<p>In other words, this method returns a <code>Promise</code> that, when resolved, will return a response of the type <code>AxiosResponse&lt;any, any&gt;</code>.</p>
<h3 id="heading-axios-built-in-generic-interface-for-response">AXIOS BUILT-IN GENERIC INTERFACE FOR RESPONSE:</h3>
<p>Let's now look at what <code>AxiosResponse&lt;any, any&gt;</code> is.</p>
<p>It is a built-in <code>interface</code> provided by the <code>Axios</code> library. Let's look at its declaration and see how it's structured.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647850262100/jFuC2JI2s.png" alt="image.png" /></p>
<p>As you can see in the image above. <code>AxiosResponse</code> is a generic interface that expects two <code>type parameters</code>, <code>T</code> and <code>D</code>, which are by default assigned to be of <code>any</code> type.</p>
<p><code>T</code> is assigned to the <code>data</code> key and <code>D</code> is assigned to the <code>config</code> key. Let's ignore the <code>config</code> key declaration for now since we generally don't modify it.</p>
<p>When we receive a response from the backend, it is generally accessible through the <code>data</code> key.</p>
<p>Therefore, we can create a custom interface for the <code>data</code> key and pass it as the first type argument to <code>AxiosResponse</code>.</p>
<p>Let's declare an interface that represents the response we receive from the back end.</p>
<p>To do that, create the file <code>type/interface.ts</code> in the <code>src</code> folder as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647850771504/0_YqLS9z9.png" alt="image.png" /></p>
<p>Add the following code to <code>type/interface.ts</code>:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> ServerResponse {
  status: <span class="hljs-built_in">number</span>;
  errorMessage: <span class="hljs-built_in">string</span>;
  success: <span class="hljs-built_in">boolean</span>;
  message: <span class="hljs-built_in">string</span>;
  result: <span class="hljs-built_in">any</span>;
}
</code></pre>
<p>The above interface shows the structure of a server response <em>(which is set by the backend developers)</em>. As developers, we know that we will receive the following keys with the success response from the backend: <em>(There might be different keys for different backends, it depends on how the backend response is structured)</em></p>
<ul>
<li><p><code>status</code> of type <code>number</code>.</p>
</li>
<li><p><code>errorMessage</code> of type <code>string</code>.</p>
</li>
<li><p><code>success</code> of type <code>boolean</code>.</p>
</li>
<li><p><code>message</code> of type <code>string</code>.</p>
</li>
<li><p><code>result</code> of type <code>any</code> because multiple responses may have different data types for the <code>result</code> key so it makes sense to use <code>any</code> here.</p>
</li>
</ul>
<p>Now let's pass the above interface to <code>AxiosResponse</code> as the first type argument as follows:</p>
<pre><code class="lang-typescript">...
<span class="hljs-keyword">class</span> ApiService {
  <span class="hljs-keyword">static</span> <span class="hljs-keyword">async</span> getCourseById(
    id: <span class="hljs-built_in">string</span>
  ): <span class="hljs-built_in">Promise</span>&lt;AxiosResponse&lt;ServerResponse, <span class="hljs-built_in">any</span>&gt;&gt; { <span class="hljs-comment">// additional code</span>
    <span class="hljs-keyword">return</span> axiosClient.get(<span class="hljs-string">`/<span class="hljs-subst">${id}</span>`</span>);
  }
}
...
</code></pre>
<h3 id="heading-response-autosuggestions">RESPONSE AUTOSUGGESTIONS:</h3>
<p>Let's try this method out in the <code>App.tsx</code> file and see what its benefits are.</p>
<p>Add the following code to the <code>App.tsx</code> file:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> React, { useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"./App.css"</span>;
<span class="hljs-keyword">import</span> ApiService <span class="hljs-keyword">from</span> <span class="hljs-string">"./api"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> fetchCourseById = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> ApiService.getCourseById(
        <span class="hljs-string">"90794953-d58f-4cde-b2ce-9e0a6643c658"</span>
      );
      <span class="hljs-built_in">console</span>.log(response);
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.log(error);
    }
  };

  useEffect(<span class="hljs-function">() =&gt;</span> {
    fetchCourseById();
  }, []);

  <span class="hljs-keyword">return</span> (
    &lt;div className=<span class="hljs-string">"App"</span>&gt;
      &lt;h1&gt;Learn typescript&lt;/h1&gt;
    &lt;/div&gt;
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>Let's see what the console displays.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647852377704/-LgmwUa96D.png" alt="image.png" /></p>
<p>If you look closely, you can see that the response structure is exactly the same as that of the <code>AxiosResponse</code> interface.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647852538529/qfTzpnjDF.png" alt="image.png" /></p>
<p>Let's see if we get suggestions for the <code>data</code> key for this <code>AxiosResponse</code> in the <code>fetchCourseById</code> function.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647852622122/aRS1wBs_E.png" alt="image.png" /></p>
<p>Yes, we got the autosuggestions because the data key in <code>AxiosResponse</code> is of type <code>ServerResponse</code>, which is our interface.</p>
<p>You can type your <code>axios</code> response this way if you have a common response structure coming from the backend. So that you can eliminate errors caused by accessing a key that does not exist or is incorrect from the server response.</p>
<h2 id="heading-conclusion">CONCLUSION:</h2>
<ul>
<li><p>In this tutorial, you explore generics as they apply to functions, interfaces, classes, and custom types. You also used generics constraints for additional type checking.</p>
</li>
<li><p>Each of these makes generics a powerful tool you have at your disposal when using TypeScript. Using them correctly will save you from repeating code over and over again, and will make the types you have written more flexible.</p>
</li>
<li><p>This is especially true if you are a library author and are planning to make your code legible for a wide audience.</p>
</li>
</ul>
<p>Make sure to subscribe to our newsletter on <a target="_blank" href="https://blog.wajeshubham.in/">https://blog.wajeshubham.in/</a> and never miss any upcoming articles related to TypeScript and programming just like this one.</p>
<p>I hope this post will help you in your journey. Keep learning!</p>
<p>My <a target="_blank" href="https://wajeshubham.in"><strong><em>Website</em></strong></a>, connect with me on <a target="_blank" href="https://www.linkedin.com/in/shubham-waje/">LinkedIn</a> and <a target="_blank" href="https://github.com/wajeshubham">GitHub</a></p>
]]></content:encoded></item><item><title><![CDATA[Advance TypeScript: Take Your Development to the Next Level]]></title><description><![CDATA[By now, we've learned about most of the types and concepts in TypeScript that are vital when working with medium-to-complex applications.
The goal of this article is to explore the more complex and advanced types and concepts used in TypeScript appli...]]></description><link>https://blog.wajeshubham.in/advance-typescript</link><guid isPermaLink="true">https://blog.wajeshubham.in/advance-typescript</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[advanced]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Shubham Waje]]></dc:creator><pubDate>Mon, 27 Feb 2023 06:44:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1677480112326/16551a4b-1282-43ef-bcc1-6bc7aa3ac794.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>By now, we've learned about most of the types and concepts in TypeScript that are vital when working with medium-to-complex applications.</p>
<p>The goal of this article is to explore the more complex and advanced types and concepts used in TypeScript applications. We'll discuss <strong>intersection types, type guards, discriminated unions, typecasting, index properties, function overloading, optional chaining, and nullish coalescing.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646455813217/b8HdkixpQ.png" alt="cover.png" /></p>
<h2 id="heading-intersection-type">INTERSECTION TYPE:</h2>
<h3 id="heading-definition-andamp-example">DEFINITION &amp; EXAMPLE:</h3>
<p>An intersection allows us to combine multiple <strong>types and interfaces</strong> into one single <code>type</code> (<strong>not interface</strong>). To create an intersection type, use the <code>&amp;</code> operator as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> Name = {
  name: <span class="hljs-built_in">string</span>;
};

<span class="hljs-keyword">type</span> Age = {
  age: <span class="hljs-built_in">number</span>;
};

<span class="hljs-keyword">type</span> Person = Name &amp; Age;
</code></pre>
<p>In the same way, let's create a new <code>type</code> by combining two <code>interfaces</code>:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Name {
  name: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">interface</span> Age {
  age: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">type</span> Person = Name &amp; Age;

<span class="hljs-keyword">let</span> p: Person = {
  name: <span class="hljs-string">"John"</span>,
  age: <span class="hljs-number">18</span>,
};
</code></pre>
<p>According to the above code, the <code>Person</code> type must contain mandatory properties of both the <code>Name</code> and <code>Age</code> interfaces.</p>
<p>If you miss any of the interface mandatory properties, you'll get a compilation error.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646768657088/ZBmOj89q4.png" alt="image.png" /></p>
<blockquote>
<p>An interface <strong>CANNOT</strong> be created by intersecting two or more <code>types</code> or <code>interfaces</code>.</p>
</blockquote>
<h3 id="heading-difference-between-union-andamp-intersection-types">DIFFERENCE BETWEEN UNION &amp; INTERSECTION TYPES:</h3>
<ul>
<li><p>In Typescript, unions and intersections are defined in the <strong>Advanced Types</strong> section.</p>
</li>
<li><p>The main difference between the two is that an <code>intersection type</code> combines multiple types into one. Whereas, a <code>union type</code> refers to a value that can be one of the multiple types.</p>
</li>
<li><p>The <code>&amp;</code> symbol represents an <code>intersection</code>, while the <code>|</code> symbol represents a <code>union</code>.</p>
</li>
<li><p>Those who have a background in programming may notice that these symbols are usually associated with logical expressions. The intersection (<code>&amp;</code>) can be considered as an <code>AND</code> whereas the union (<code>|</code>) can be considered as an <code>OR</code>.</p>
</li>
</ul>
<p>To better understand the difference, let's look at an example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> FlyingAnimal {
  flyingSpeed: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">interface</span> SwimmingAnimal {
  swimmingSpeed: <span class="hljs-built_in">number</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getSmallPet</span>(<span class="hljs-params"></span>): <span class="hljs-title">FlyingAnimal</span> | <span class="hljs-title">SwimmingAnimal</span> </span>{
  <span class="hljs-keyword">return</span> {
    flyingSpeed: <span class="hljs-number">1</span>,
  };
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getFlyingFish</span>(<span class="hljs-params"></span>): <span class="hljs-title">FlyingAnimal</span> &amp; <span class="hljs-title">SwimmingAnimal</span> </span>{
  <span class="hljs-keyword">return</span> {
    flyingSpeed: <span class="hljs-number">1</span>,
    swimmingSpeed: <span class="hljs-number">1</span>,
  };
}
</code></pre>
<p>In this example, we have two interfaces: <code>FlyingAnimal</code> and <code>SwimmingAnimal</code>. Furthermore, we have two functions <code>getSmallPet</code> with a return type of <code>FlyingAnimal | SwimmingAnimal</code> (union type) and <code>getFlyingFish</code> with a return type of <code>FlyingAnimal &amp; SwimmingAnimal</code>.</p>
<p>Since the <code>getSmallPet</code> return type is union, you should return <strong>all the mandatory properties of at least one</strong> of the types/interfaces included in the union.</p>
<p>Thus, we returned <code>{ flyingSpeed: 1 }</code>, which is a property of the <code>FlyingAnimal</code> interface.</p>
<p>On the other hand, in <code>intersection type</code>, you need to return <strong>all the mandatory properties of every</strong> type/interface included in the intersection.</p>
<p>Therefore, we have returned <code>{ flyingSpeed: 1, swimmingSpeed: 1 }</code>, if we miss any of the mandatory properties in <code>getFlyingFish</code>, we will receive the following compilation error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646457188945/IOtpyhU02.png" alt="image.png" /></p>
<h3 id="heading-when-to-use-it">WHEN TO USE IT?</h3>
<p>Instead of using intersections, we can just combine all the properties of the two types/interfaces that we want to intersect.</p>
<p>However, we may have two interfaces that are used separately as types somewhere in the program. To create a new type composed of the properties of these interfaces, we will <code>intersect</code> them rather than rewrite their properties.</p>
<p>let's take an example to understand this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> I1 {
  a: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">interface</span> I2 {
  b: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">let</span> i1: I1 = {
  a: <span class="hljs-number">1</span>,
};

<span class="hljs-keyword">let</span> i2: I2 = {
  b: <span class="hljs-number">2</span>,
};

<span class="hljs-keyword">let</span> combinedI: I1 &amp; I2 = {
  a: <span class="hljs-number">1</span>,
  b: <span class="hljs-number">2</span>,
};
</code></pre>
<p>There are two interfaces <code>I1</code> and <code>I2</code> that are used independently in variables <code>i1</code> and <code>i2</code>.</p>
<p>Additionally, we have the <code>combinedI</code> variable, which has an intersection type of both <code>I1</code> and <code>I2</code>.</p>
<p>So instead of creating a new type/interface for the <code>combinedI</code> with properties <code>a</code> and <code>b</code>, we just intersect the available interfaces <code>I1</code> and <code>I2</code>.</p>
<h2 id="heading-type-guards">TYPE GUARDS:</h2>
<ul>
<li><p>A <strong>Type Guard</strong> reduces the type of an object in a conditional block. Basically, it is an additional piece of code we write to prevent errors at runtime</p>
</li>
<li><p>Some of the most famous <strong>Type Guards</strong> are <code>typeof</code>, <code>in</code>, and <code>instanceof</code>.</p>
</li>
</ul>
<h3 id="heading-typeof-operator"><code>typeof</code> OPERATOR:</h3>
<p>In our previous blog <a target="_blank" href="https://blog.wajeshubham.in/everyday-types-in-typescript#heading-handle-compilation-error-using-type-guards">Everyday Types in TypeScript</a>, we looked at how type guards could be used to add type-checking to avoid compilation errors.</p>
<p>To understand it better, let's look at some more examples:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> alphanumeric = <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">a: alphanumeric, b: alphanumeric</span>) </span>{
  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> a === <span class="hljs-string">"number"</span> &amp;&amp; <span class="hljs-keyword">typeof</span> b === <span class="hljs-string">"number"</span>) {
    <span class="hljs-keyword">return</span> a + b;
  }

  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> a === <span class="hljs-string">"string"</span> &amp;&amp; <span class="hljs-keyword">typeof</span> b === <span class="hljs-string">"string"</span>) {
    <span class="hljs-keyword">return</span> a.concat(b);
  }

  <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Invalid parameters"</span>); <span class="hljs-comment">// return when a and b are not of the same type</span>
}
</code></pre>
<p>In this example, we have a union-type <code>alphanumeric</code>, which can be either <code>string</code> or <code>number</code>. Also, we have a simple <code>add</code> function that has two parameters <code>a</code> and <code>b</code> of the type <code>alphanumeric</code>.</p>
<p>In it, we add a type guard for checking whether both parameters have the same types, and then we perform some operations.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> a === <span class="hljs-string">"number"</span> &amp;&amp; <span class="hljs-keyword">typeof</span> b === <span class="hljs-string">"number"</span>) {
    <span class="hljs-keyword">return</span> a + b;
  }
</code></pre>
<p>This block checks whether parameters <code>a</code> and <code>b</code> are <code>number</code> types. If they are, we will <strong>add</strong> them.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> a === <span class="hljs-string">"string"</span> &amp;&amp; <span class="hljs-keyword">typeof</span> b === <span class="hljs-string">"string"</span>) {
    <span class="hljs-keyword">return</span> a.concat(b);
  }
</code></pre>
<p>This block checks whether parameters <code>a</code> and <code>b</code> are <code>string</code> types. If they are, we will <strong>concatenate</strong> them.</p>
<h3 id="heading-instanceof-operator"><code>instanceof</code> OPERATOR:</h3>
<p>As discussed in our previous blog on <a target="_blank" href="https://blog.wajeshubham.in/classes-in-typescript">Classes in TypeScript</a>, the <code>class</code> can be used as a valid TypeScript type.</p>
<p>The <code>instanceof</code> operator can be used to check whether a variable is an instance of a class.</p>
<p>Here's an example to help you understand:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Car {
  drive() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Driving a car..."</span>);
  }
}

<span class="hljs-keyword">class</span> Truck {
  drive() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Driving a truck..."</span>);
  }
  loadCargo() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Loading cargo on truck..."</span>);
  }
}

<span class="hljs-keyword">type</span> Vehicle = Car | Truck;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useVehicle</span>(<span class="hljs-params">v: Vehicle</span>) </span>{
  v.drive();
  v.loadCargo(); <span class="hljs-comment">// we get compilation error here</span>
}
</code></pre>
<p>We have two classes in the above code: <code>Car</code> and <code>Truck</code>. Both classes have a common method called <code>drive()</code>, while class <code>Truck</code> has an additional method called <code>loadCargo()</code>.</p>
<p>Then we are creating a new type called <code>Vehicle</code>, which is a union of <code>Car</code> and <code>Truck</code>.</p>
<p>Hence, the <code>Vehicle</code> type may or may not have all the properties of both <code>Car</code> and <code>Truck</code>.</p>
<p>Furthermore, we have a function <code>useVehicle</code> which accepts a parameter <code>v</code> of type <code>Vehicle</code>, and inside it, we access the methods <code>drive()</code> and <code>loadCargo()</code>.</p>
<p>However, we are unable to access the <code>loadCardo()</code> method due to a compilation error. Take a look at the following picture:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646460145853/wMaQwokzc.png" alt="image.png" /></p>
<p>This is because the <code>drive()</code> method is available in both <code>Car</code> and <code>Truck</code> classes, but the <code>loadCargo()</code> method is only available in the <code>Truck</code> class. Since the <code>Vehicle</code> is a union type, there is a chance that you could pass a parameter of type <code>Car</code> that does not have the <code>loadCargo()</code> method.</p>
<p>To avoid this error, we can create a type guard by using the <code>instanceof</code> keyword:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useVehicle</span>(<span class="hljs-params">v: Vehicle</span>) </span>{
  v.drive();
  <span class="hljs-keyword">if</span> (v <span class="hljs-keyword">instanceof</span> Truck) { <span class="hljs-comment">// type guard</span>
    v.loadCargo(); <span class="hljs-comment">// runs without error</span>
  }
}
</code></pre>
<p>This means that only if <code>v</code> is an instance of the class <code>Truck</code>, execute the next line of code.</p>
<h3 id="heading-in-operator"><code>in</code> OPERATOR:</h3>
<p>The <code>in</code> operator performs a safety check on the existence of a property in an <code>object</code>. This can also be used as a <code>type guard</code>. For instance:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Developer {
  developmentTools: <span class="hljs-built_in">string</span>[];
}

<span class="hljs-keyword">interface</span> Tester {
  testingTools: <span class="hljs-built_in">string</span>[];
}

<span class="hljs-keyword">type</span> Employee = Developer | Tester;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getToolsUsed</span>(<span class="hljs-params">employee: Employee</span>) </span>{
  <span class="hljs-built_in">console</span>.log(employee.developmentTools); <span class="hljs-comment">// compilation errors</span>
  <span class="hljs-built_in">console</span>.log(employee.testingTools); <span class="hljs-comment">// compilation errors</span>
}

<span class="hljs-keyword">let</span> developer: Employee = {
  developmentTools: [<span class="hljs-string">"typescript"</span>, <span class="hljs-string">"react"</span>],
};
</code></pre>
<p>We have two interfaces, <code>Developer</code> and <code>Tester</code>, with both having the <code>developmentTools</code> and <code>testingTools</code> properties of type <code>string[]</code> respectively.</p>
<p>After that, we declare a new type <code>Employee</code> that is a union type.</p>
<p>We also have a function <code>getToolsUsed</code> that accepts a parameter <code>employee</code> of type <code>Employee</code>.</p>
<p>We thus encounter a compilation error when we try to access a <code>developmentTools</code> or a <code>testingTools</code> through the <code>employee</code> parameter because that object may or may not have those properties.</p>
<p>We can prevent this by adding a <code>type guard</code> using the <code>in</code> operator, as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getToolsUsed</span>(<span class="hljs-params">employee: Developer | Tester</span>) </span>{
  <span class="hljs-keyword">if</span> (<span class="hljs-string">"developmentTools"</span> <span class="hljs-keyword">in</span> employee) {
    <span class="hljs-comment">// only works if the employee has the property developmentTools</span>
    <span class="hljs-built_in">console</span>.log(employee.developmentTools); <span class="hljs-comment">// runs without error</span>
  }
  <span class="hljs-keyword">if</span> (<span class="hljs-string">"testingTools"</span> <span class="hljs-keyword">in</span> employee) {
    <span class="hljs-comment">// only works if the employee has the property testingTools</span>
    <span class="hljs-built_in">console</span>.log(employee.testingTools); <span class="hljs-comment">// runs without error</span>
  }
}
</code></pre>
<h3 id="heading-discriminated-union">DISCRIMINATED UNION:</h3>
<p>Discriminated union type guard is a design pattern you use to ensure a runtime error won't occur because the property that doesn't exist is accessed.</p>
<p>As an example, let's replace <code>in</code> in the above example with a discriminated union-type guard.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Developer {
  role: <span class="hljs-string">"developer"</span>;
  developmentTools: <span class="hljs-built_in">string</span>[];
}

<span class="hljs-keyword">interface</span> Tester {
  role: <span class="hljs-string">"tester"</span>;
  testingTools: <span class="hljs-built_in">string</span>[];
}

<span class="hljs-keyword">let</span> Employee: Developer | Tester;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getToolsUsed</span>(<span class="hljs-params">employee: Developer | Tester</span>) </span>{
  <span class="hljs-keyword">switch</span> (employee.role) {
    <span class="hljs-keyword">case</span> <span class="hljs-string">"developer"</span>:
      <span class="hljs-built_in">console</span>.log(employee.developmentTools); <span class="hljs-comment">// valid code</span>
      <span class="hljs-keyword">break</span>;
    <span class="hljs-keyword">case</span> <span class="hljs-string">"tester"</span>:
      <span class="hljs-built_in">console</span>.log(employee.testingTools); <span class="hljs-comment">// valid code</span>
      <span class="hljs-keyword">break</span>;
  }
}
</code></pre>
<p>To all of the interfaces that are included while creating a <code>union type</code>, we are assigning a <code>role</code> property - a <code>literal type</code> (click <a target="_blank" href="https://blog.wajeshubham.in/everyday-types-in-typescript#heading-literal-types">here</a> for more information about literal types).</p>
<p>Lastly, we used the <code>role</code> property as a differentiator in switch-case statements.</p>
<h2 id="heading-index-properties">INDEX PROPERTIES:</h2>
<p>Index signatures look similar to property signatures, but with one difference. Instead of writing the property name, you simply place the type of key within square brackets.</p>
<h3 id="heading-syntax-and-declaration">SYNTAX AND DECLARATION:</h3>
<p>Take a look at the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> StringObject {
  [key: <span class="hljs-built_in">string</span>]: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">const</span> strings: StringObject = {
  en_US: <span class="hljs-string">"Hello, World!"</span>,
  fr_FR: <span class="hljs-string">"Bonjour, le monde!"</span>,
  es_ES: <span class="hljs-string">"¡Hola, mundo!"</span>,
  de_DE: <span class="hljs-string">"Hallo, Welt!"</span>,
};
</code></pre>
<p>Here we have a <code>StringObject</code> interface with a <code>string</code> <code>key</code> and <code>string</code> <code>value</code> structure. We will receive the following compilation error if we break the rules:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645469724439/4rpWcqd4z.png" alt="image.png" /></p>
<h3 id="heading-use-case-of-index-signature">USE CASE OF INDEX SIGNATURE:</h3>
<p>The purpose of index signatures is to type objects of unknown structure when only key and value types are known.</p>
<p>To understand this, let's look at an example.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> SalaryStructure {
  [key: <span class="hljs-built_in">string</span>]: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">let</span> developerSalary: SalaryStructure = {
  baseSalary: <span class="hljs-number">10000</span>,
  bonus: <span class="hljs-number">100</span>,
  incentive: <span class="hljs-number">50</span>,
  appreciationBonus: <span class="hljs-number">10</span>,
};

<span class="hljs-keyword">const</span> getTotalSalary = (salaryObject: SalaryStructure): <span class="hljs-function"><span class="hljs-params">number</span> =&gt;</span> {
  <span class="hljs-keyword">let</span> total = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> name <span class="hljs-keyword">in</span> salaryObject) {
    total += salaryObject[name];
  }
  <span class="hljs-keyword">return</span> total;
};

<span class="hljs-built_in">console</span>.log(getTotalSalary(developerSalary)); <span class="hljs-comment">// prints: 10160 rupees</span>
</code></pre>
<p>Above we have an interface <code>SalaryStructure</code> that is declared with an <strong>index signature</strong>. This demonstrates that the <code>SalaryStructure</code> interface will have <code>keys</code> of type <code>string</code> and values of type <code>number</code>.</p>
<p>Next, we declare a variable <code>developerSalary</code> which is of type <code>SalaryStructure</code>. Furthermore, we are creating a function <code>getTotalSalary</code> that accepts a <code>salary</code> object of type <code>SalaryStructure</code>.</p>
<p>As we know that <code>salaryObject</code> will be an object with a <code>string</code> key and a <code>number</code> value, we can use the for loop to loop through the <code>salaryObject</code> to calculate the total salary.</p>
<h3 id="heading-disadvantage">DISADVANTAGE:</h3>
<p>This syntax has the drawback of not having auto-suggestions supported by the IDE. Because IDE doesn't know the exact key that an object holds, it only knows the type of key it holds.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645469844387/yYo462Q7B.png" alt="image.png" /></p>
<p>In addition, it doesn't raise a compilation error when we try to access a key that doesn't exist in the object, as you can see in the following image.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645470018973/nt33xVmu7.png" alt="image.png" /></p>
<h2 id="heading-typecasting">TYPECASTING:</h2>
<ul>
<li><p>In typecasting, a variable is transformed from one type to another.</p>
</li>
<li><p>JavaScript does not have a concept of type casting since variables have dynamic types.</p>
</li>
<li><p>By typecasting, you can tell TypeScript that a particular value is of a specific type, which would otherwise be impossible for TypeScript to detect by itself.</p>
</li>
</ul>
<h3 id="heading-accessing-a-dom-element">ACCESSING A DOM ELEMENT:</h3>
<p>TypeScript warns you when properties/methods are called on DOM elements.</p>
<p>Here's an example to help you understand:</p>
<blockquote>
<p>To run the following code snippets, you need to have <code>typescript</code> installed globally. If you don't have <code>typescript</code> installed, run <code>npm install -g typescript</code> in your terminal or check out my blog on <a target="_blank" href="https://blog.wajeshubham.in/introduction-to-typescript#heading-lets-set-up-a-project">Introduction to TypeScript</a> to get started.</p>
</blockquote>
<p>In the root folder, create the <code>index.html</code> and <code>index.ts</code> files.</p>
<p>In <code>index.html</code>, add the following code:</p>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Typescript<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-inp"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>In <code>index.ts</code>, add the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> myInput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"my-inp"</span>);

<span class="hljs-built_in">console</span>.log(myInput.value) <span class="hljs-comment">// throws error</span>
</code></pre>
<p>In the above code, we are trying to get a DOM element by its <code>id</code>. The problem is that TypeScript does not know what type of element we are attempting to access.</p>
<p>So it infers it to be an element with type <code>HTMLElement | null</code>, as seen in the following image:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646469084811/hxoQUvgoF.png" alt="image.png" /></p>
<p>As a developer, we know that the <code>myInput</code> can't be <code>null</code> since <code>index.html</code> has an <code>input</code> tag with the <code>id="my-inp"</code>.</p>
<p>To inform TypeScript that the element with the <code>id="my-inp"</code> exists we can use <code>!</code> at the end of the value that might be <code>null</code>, as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> myInput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"my-inp"</span>)!;
</code></pre>
<p>Now, if you hover over <code>myInput</code> you will see the type as <code>HTMLElement</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646469305664/5K65lB5Ag.png" alt="image.png" /></p>
<p>However, all DOM elements that are <code>HTMLElement</code> does not have a property called <code>value</code>. Yet, as a developer, we are aware that we are trying to access an <code>input</code> element that has a <code>value</code> property.</p>
<p>Therefore, to tell TypeScript that this element is of type <code>HTMLInputElement</code>, we shall use <strong>Type Casting</strong>.</p>
<p>For type casing, there are two different syntaxes to choose from:</p>
<h3 id="heading-typecast-using-andltandgt-operator">TYPECAST USING <code>&lt;&gt;</code> OPERATOR:</h3>
<p>The syntax we use to typecast the above code snippet uses the <code>&lt;&gt;</code> operator is as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> myInput = &lt;HTMLInputElement&gt;<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"my-inp"</span>)! ;

<span class="hljs-built_in">console</span>.log(myInput.value) <span class="hljs-comment">// runs without error</span>
</code></pre>
<blockquote>
<p>It is not a recommended way of doing typecasting because it is similar to <strong>JSX</strong>.</p>
</blockquote>
<h3 id="heading-typecast-using-as-keyword">TYPECAST USING <code>as</code> KEYWORD:</h3>
<p>The syntax we use to typecast the above code snippet uses the <code>as</code> keyword is as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> myInput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"my-inp"</span>)! <span class="hljs-keyword">as</span> HTMLInputElement;

<span class="hljs-built_in">console</span>.log(myInput.value); <span class="hljs-comment">// runs without error</span>
</code></pre>
<h2 id="heading-function-overloading">FUNCTION OVERLOADING:</h2>
<p>TypeScript supports the concept of <code>function overloading</code>. Multiple functions can share the same name, but have different parameter types and return types. However, the number of parameters must be the same.</p>
<p>Let's take an example to understand this concept.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> Param = <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">a: Param, b: Param</span>) </span>{
  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> a === <span class="hljs-string">"string"</span> || <span class="hljs-keyword">typeof</span> b === <span class="hljs-string">"string"</span>) {
    <span class="hljs-comment">// even if any of the value in `number` we are converting to string</span>
    <span class="hljs-keyword">return</span> a.toString() + b.toString();
  }
  <span class="hljs-keyword">return</span> a + b;
}

<span class="hljs-keyword">let</span> result = add(<span class="hljs-string">"John "</span>, <span class="hljs-string">"Doe"</span>);
</code></pre>
<p>In the code above, we have a custom type called <code>Param</code> that is a union type. Furthermore, we have an <code>add</code> function that accepts two parameters <code>a</code> and <code>b</code>, both of type <code>Param</code>.</p>
<p>Let's see what inferred type the <code>result</code> variable has if we run the <code>add</code> function with both parameters of the type <code>string</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646474189243/IHsxMQcC0.png" alt="image.png" /></p>
<p>As you can see in the above image, it appears to be a <code>string | number</code> variable, which is correct to a certain extent, but it would cause a problem if we attempted to access any string method on the <code>result</code> variable.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646474354756/Py3RGVY_q.png" alt="image.png" /></p>
<p>Since we are passing two <code>strings</code>, the return type must also be a <code>string</code>.</p>
<p>To fix this, we are going to implement function overloading as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> Param = <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">a: <span class="hljs-built_in">string</span>, b: <span class="hljs-built_in">string</span></span>): <span class="hljs-title">string</span></span>;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">a: <span class="hljs-built_in">string</span>, b: <span class="hljs-built_in">number</span></span>): <span class="hljs-title">string</span></span>;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">string</span></span>): <span class="hljs-title">string</span></span>;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span></span>): <span class="hljs-title">number</span></span>;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">a: Param, b: Param</span>) </span>{
  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> a === <span class="hljs-string">"string"</span> || <span class="hljs-keyword">typeof</span> b === <span class="hljs-string">"string"</span>) {
    <span class="hljs-comment">// even if any of the value in `number` we are converting to string</span>
    <span class="hljs-keyword">return</span> a.toString() + b.toString();
  }
  <span class="hljs-keyword">return</span> a + b;
}

<span class="hljs-keyword">let</span> result = add(<span class="hljs-string">"John "</span>, <span class="hljs-string">"Doe"</span>);
result.split(<span class="hljs-string">" "</span>); <span class="hljs-comment">// ["John", "Doe"] runs without an error</span>
</code></pre>
<p>Here we are overloading a function <code>add</code> by specifying all possible combinations of parameter types and expected return types. Therefore, now if we attempt to determine the inferred type of the <code>result</code> variable, we will get a <code>string</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646474524837/V7nCqiaIb.png" alt="image.png" /></p>
<h2 id="heading-optional-chaining">OPTIONAL CHAINING:</h2>
<p>Consider a situation where you are making an API call and you don't know what data you will receive in the response.</p>
<p>In that case, you must use additional logic before accessing the nested object within the response data.</p>
<p>Let's take an example to understand this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> getCourse = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-comment">// following api call will return {"id":1,"name":"typescript","description":"this is the description"}</span>
  <span class="hljs-keyword">await</span> fetch(
    <span class="hljs-string">"https://jsonware.com/api/v1/json/7ece5b94-268b-4b86-a3cd-aa0eb2f9b62b"</span>,
    {
      method: <span class="hljs-string">"GET"</span>,
    }
  )
    .then(<span class="hljs-function">(<span class="hljs-params">res</span>) =&gt;</span> res.json())
    .then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(data); <span class="hljs-comment">// data is the response from the API which is uncertain</span>
    });
};

getCourse();
</code></pre>
<p>Our async function <code>getCourse</code> calls an API, and once the request is successful, we return the resultant object as <code>data</code>.</p>
<p>For instance, let's say a <code>data</code> object has an <code>id</code>, <code>name</code>, and <code>description</code> keys, but we accidentally accessed the <code>price</code> key, which doesn't exist.</p>
<p>Since the <code>data</code> has been inferred to be of <code>any</code> type, TypeScript will not throw an error instead it will ignore it.</p>
<p>Let's check out what happens when we access the <code>price</code> key.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646485218474/JAI32JRs5.png" alt="image.png" /></p>
<p>Here is what we see in the console.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646485263049/1817eP_0f.png" alt="image.png" /></p>
<p>It will throw a runtime error that states <code>Cannot read properties of undefined (reading 'toFixed')</code>.</p>
<p>In this case, we can use <strong>Optional Chaining</strong> by adding <code>?</code> after the key name that might be <code>null</code> or <code>undefined</code> as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// ...</span>
 .then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(data.price?.toFixed(<span class="hljs-number">2</span>)); <span class="hljs-comment">// this will fail silently</span>
 });
<span class="hljs-comment">// ...</span>
</code></pre>
<p>Here is what we see in the console.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646485403079/vpJcu90Ms.png" alt="image.png" /></p>
<p>It prints <code>undefined</code> without throwing a runtime error.</p>
<h2 id="heading-nullish-coalescing">NULLISH COALESCING:</h2>
<p>Nullish coalescing is a loosely related concept to <strong>optional chaining</strong>, which is used to deal with <code>undefined</code> or <code>null</code> values.</p>
<p>Let's take an example to help you understand:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> inputValue = <span class="hljs-literal">null</span>;

<span class="hljs-keyword">let</span> ignoreNullAndUndefined = inputValue || <span class="hljs-string">'default'</span>;

<span class="hljs-built_in">console</span>.log(ignoreNullAndUndefined); <span class="hljs-comment">// prints 'default'</span>
</code></pre>
<p>We have a variable called <code>inputValue</code> with the value <code>null</code>, as well as a variable called <code>ignoreNullAndUndefined</code> that accepts values other than <code>null</code> and <code>undefined</code>.</p>
<p>Therefore, we used the <code>||</code> (OR) operator to ensure <code>ignoreNullAndUndefined</code> does not receive <code>null</code> or <code>undefined</code> values.</p>
<p>The problem occurs when we declare <code>inputValue</code> as <code>""</code> (empty string). Because the <code>||</code> (OR) operator treats it as a <code>falsey</code> value, which we don't want.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1646486182146/gzqETsFWf.png" alt="image.png" /></p>
<p>Only <code>null</code> and <code>undefined</code> should be discarded.</p>
<p>Therefore, we can use the <strong>nullish coalescing operator</strong> <code>??</code> to only avoid <code>null</code> and <code>undefined</code> as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> inputValue1 = <span class="hljs-number">0</span>;
<span class="hljs-keyword">let</span> inputValue2 = <span class="hljs-string">""</span>;
<span class="hljs-keyword">let</span> inputValue3 = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">let</span> inputValue4 = <span class="hljs-literal">null</span>;

<span class="hljs-keyword">let</span> ignoreNullAndUndefined1 = inputValue1 ?? <span class="hljs-string">"default"</span>;
<span class="hljs-keyword">let</span> ignoreNullAndUndefined2 = inputValue2 ?? <span class="hljs-string">"default"</span>;
<span class="hljs-keyword">let</span> ignoreNullAndUndefined3 = inputValue3 ?? <span class="hljs-string">"default"</span>;
<span class="hljs-keyword">let</span> ignoreNullAndUndefined4 = inputValue4 ?? <span class="hljs-string">"default"</span>;

<span class="hljs-built_in">console</span>.log(ignoreNullAndUndefined1); <span class="hljs-comment">// prints 0</span>
<span class="hljs-built_in">console</span>.log(ignoreNullAndUndefined2); <span class="hljs-comment">// prints ""</span>
<span class="hljs-built_in">console</span>.log(ignoreNullAndUndefined3); <span class="hljs-comment">// prints false</span>
<span class="hljs-built_in">console</span>.log(ignoreNullAndUndefined4); <span class="hljs-comment">// prints "default"</span>
</code></pre>
<p><code>??</code> will only and only discard <code>null</code> and <code>undefined</code> and accept any other value, regardless of its truthiness or falsity.</p>
<h2 id="heading-conclusion">CONCLUSION:</h2>
<ul>
<li><p>Despite TypeScript being very simple to grasp when performing basic tasks, knowing how its type system works is crucial to unlocking its advanced capabilities.</p>
</li>
<li><p>Once we understand how TypeScript works, we can use this knowledge to write cleaner, well-organized code.</p>
</li>
<li><p>Hopefully, this article has helped to demystify parts of the TypeScript type system and give you some ideas about how you can exploit its advanced features to improve your TypeScript application structure.</p>
</li>
</ul>
<p>Make sure to subscribe to our newsletter on <a target="_blank" href="https://blog.wajeshubham.in/">https://blog.wajeshubham.in/</a> and never miss any upcoming articles related to TypeScript and programming just like this one.</p>
<p>I hope this post will help you in your journey. Keep learning!</p>
<p>My <a target="_blank" href="https://wajeshubham.in"><strong><em>Website</em></strong></a>, connect with me on <a target="_blank" href="https://www.linkedin.com/in/shubham-waje/">LinkedIn</a> and <a target="_blank" href="https://github.com/wajeshubham">GitHub</a></p>
]]></content:encoded></item><item><title><![CDATA[Interfaces in TypeScript]]></title><description><![CDATA[Last article, we talked about TypeScript classes, how to use them effectively, and all of the fundamental concepts associated with them.
In this article, we’ll create interfaces, learn how to use them, explore the differences between normal types and...]]></description><link>https://blog.wajeshubham.in/interfaces-in-typescript</link><guid isPermaLink="true">https://blog.wajeshubham.in/interfaces-in-typescript</guid><category><![CDATA[Interfaces]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Shubham Waje]]></dc:creator><pubDate>Thu, 26 Jan 2023 12:01:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1674734335244/64437a5c-d4cd-4926-8efd-942f32074854.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Last <a target="_blank" href="https://blog.wajeshubham.in/classes-in-typescript">article</a>, we talked about TypeScript classes, how to use them effectively, and all of the fundamental concepts associated with them.</p>
<p>In this article, we’ll create interfaces, learn how to use them, explore the differences between normal types and interfaces, and learn about declaration and merging.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645174358379/SXJbvJGlS.png" alt="image.png" /></p>
<h2 id="heading-what-is-an-interface">WHAT IS AN INTERFACE?</h2>
<blockquote>
<p><strong>An Interface is a structure that acts as a contract/doc in our application. It defines the syntax for classes/objects to follow, which means a class/object which implements an interface is bound to implement all its members (except for optional properties/methods)</strong>.</p>
<p><strong>The interface contains only the declaration of the methods and fields, but not the implementation. It is a shape of an object.</strong></p>
</blockquote>
<h2 id="heading-syntax-andamp-declaration">SYNTAX &amp; DECLARATION:</h2>
<h3 id="heading-create-an-interface">CREATE AN INTERFACE:</h3>
<p>Interfaces in TypeScript are created by using the <code>interface</code> keyword followed by the name of the interface, and then a <code>{}</code> block with the body of the interface. For example, here is a <code>Course</code> interface:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Course {
  name: <span class="hljs-built_in">string</span>;
  price: <span class="hljs-built_in">number</span>;
  isFree: <span class="hljs-built_in">boolean</span>;
  onPurchase: <span class="hljs-function">(<span class="hljs-params">userId: <span class="hljs-built_in">string</span></span>) =&gt;</span> <span class="hljs-built_in">void</span>;
}
</code></pre>
<p>Similar to creating a normal <code>type</code> using the type declaration, you specify the fields/properties of the <code>interface</code>, and their types, in the <code>{}</code>:</p>
<p>The above <code>Course</code> interface represents an object that has four properties which are <code>name</code> of type <code>string</code>, <code>price</code> of type <code>number</code>, <code>isFree</code> of type <code>boolean</code>, and <code>onPurchase</code> which is a function that accepts a single parameter <code>userId</code> of type <code>string</code> and returns <code>void</code>.</p>
<h3 id="heading-use-the-interface-as-a-valid-type">USE THE INTERFACE AS A VALID TYPE:</h3>
<p>Now the <code>Course</code> interface is a valid TypeScript type. It can be used like any other type. An example of creating an object literal that matches the <code>Course</code> interface is as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> course: Course = {
  name: <span class="hljs-string">"Angular"</span>,
  price: <span class="hljs-number">100</span>,
  isFree: <span class="hljs-literal">true</span>,
  onPurchase: <span class="hljs-function">(<span class="hljs-params">userId: <span class="hljs-built_in">string</span></span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`User with id <span class="hljs-subst">${userId}</span> has purchased <span class="hljs-subst">${course.name}</span>`</span>);
  },
};
</code></pre>
<p>Variables using the <code>Course</code> interface as their type must have the same members as those specified in the <code>Course</code> interface declaration.</p>
<p>If you miss any one of the members you will get a compilation error as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645212450441/X4Y-HQgpa.png" alt="image.png" /></p>
<h3 id="heading-optional-properties">OPTIONAL PROPERTIES:</h3>
<p>If you want to resolve the above error, you must include the property or make the particular property <code>optional</code> by adding <code>?</code> ahead of <code>:</code> as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Course {
  name: <span class="hljs-built_in">string</span>;
  price: <span class="hljs-built_in">number</span>;
  isFree: <span class="hljs-built_in">boolean</span>;
  onPurchase?: <span class="hljs-function">(<span class="hljs-params">userId: <span class="hljs-built_in">string</span></span>) =&gt;</span> <span class="hljs-built_in">void</span>; <span class="hljs-comment">// this is an optional property</span>
}

<span class="hljs-comment">// No compilation error</span>
<span class="hljs-keyword">let</span> course: Course = {
  name: <span class="hljs-string">"Angular"</span>,
  price: <span class="hljs-number">100</span>,
  isFree: <span class="hljs-literal">true</span>,
};
</code></pre>
<p>However, when you make any property optional, TypeScript automatically infers that property to be of type <code>&lt;your given type&gt; | undefined</code>.</p>
<p>If you hover over the <code>onPurchase</code> property, you'll see that TypeScript has inferred the type as <code>((userId: string) =&gt; void) | undefined</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645212911721/kiXAykqKO.png" alt="image.png" /></p>
<p>To avoid compile-time errors when working with such properties, type guards must be used. Type guards are nothing more than extra type-checking.</p>
<blockquote>
<p>We will discuss Type guards in depth in future blogs.</p>
</blockquote>
<h3 id="heading-readonly-properties">READONLY PROPERTIES:</h3>
<p>You can add read-only properties to an interface using the <code>readonly</code> keyword. This is similar to the last time we discussed how to create read-only properties inside a class with the <code>readonly</code> modifier.</p>
<p>Whenever we want to declare a property as read-only, we put the <code>readonly</code> keyword before the name of the property inside an <code>interface</code>, as shown below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Course {
  name: <span class="hljs-built_in">string</span>;
  <span class="hljs-keyword">readonly</span> price: <span class="hljs-built_in">number</span>; <span class="hljs-comment">// readonly property</span>
  isFree: <span class="hljs-built_in">boolean</span>;
  onPurchase?: <span class="hljs-function">(<span class="hljs-params">userId: <span class="hljs-built_in">string</span></span>) =&gt;</span> <span class="hljs-built_in">void</span>; <span class="hljs-comment">// this is an optional property</span>
}

<span class="hljs-comment">// No compilation error</span>
<span class="hljs-keyword">let</span> course: Course = {
  name: <span class="hljs-string">"Angular"</span>,
  price: <span class="hljs-number">100</span>,
  isFree: <span class="hljs-literal">true</span>,
};

course.name = <span class="hljs-string">"Angular updated name"</span>
course.price = <span class="hljs-number">150</span>; <span class="hljs-comment">// throws compilation error</span>
</code></pre>
<p><code>price</code> is a <code>readonly</code> property in the above code, so you can only provide a value while declaring a variable, you can't modify it afterward. Doing so will result in the following compilation error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645256459450/oVnQD_res.png" alt="image.png" /></p>
<p><strong>NOTE: In an interface, you can only use the</strong> <code>readonly</code> modifier. You CAN NOT use other modifiers like <code>private</code>, <code>public</code>, or <code>protected</code> inside an <code>interface</code>.</p>
<h2 id="heading-is-interface-a-thing-in-javascript">IS INTERFACE A THING IN JAVASCRIPT?</h2>
<ul>
<li><p><strong>In JavaScript, the interface is not a thing</strong>. They are used to define a type of object or implement it in a class, <strong>but only in TypeScript.</strong></p>
</li>
<li><p>TypeScript Interface has zero JavaScript code which means it is only available in TypeScript and does not produce any code in compiled JavaScript files. This is also known as "duck typing" or "structural subtyping".</p>
</li>
</ul>
<p>To understand the second point let's take an example:</p>
<p>In our first blog, we learned that whenever our typescript is compiled, it's converted into JavaScript. Therefore, let us create an interface and write some logic to see what the equivalent code looks like in JavaScript.</p>
<p>Take a look at the following code:</p>
<blockquote>
<p>For this, you need a basic project setup. Check out my blog on <a target="_blank" href="https://blog.wajeshubham.in/introduction-to-typescript#heading-installation">Introduction to Typescript</a> which includes detailed instructions on how to compile TS files into JS files including the tools and libraries necessary.</p>
</blockquote>
<p>Create an <code>index.ts</code> file and add the following code to it:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Course {
  name: <span class="hljs-built_in">string</span>;
  price: <span class="hljs-built_in">number</span>;
  isFree: <span class="hljs-built_in">boolean</span>;
}

<span class="hljs-keyword">let</span> course: Course = {
  name: <span class="hljs-string">"Angular"</span>,
  price: <span class="hljs-number">100</span>,
  isFree: <span class="hljs-literal">true</span>,
};

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Created course: "</span>, course);
</code></pre>
<p>Then, run the following command to compile the <code>index.ts</code> into JavaScript:</p>
<pre><code class="lang-bash">tsc index.ts
</code></pre>
<p>This will generate an <code>index.js</code> file that contains equivalent JavaScript code. If you open that file, you will see that there is no trace of an <code>interface</code>. Instead, you will see only a variable declaration and a console log statement. Here is an example of what that would look like:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645256979145/lii89as_9.png" alt="image.png" /></p>
<p>The reason is that JavaScript cannot understand interfaces. An <code>interface</code> is a development feature only found in TypeScript. It aims to improve code quality by adding type checks, preventing compilation errors, and ensuring bug-free code.</p>
<blockquote>
<p>Some libraries help create interfaces in JavaScript, such as <a target="_blank" href="https://www.npmjs.com/package/implement-js"><code>implement.js</code></a>, but if you want them, why not use TypeScript instead?</p>
</blockquote>
<h2 id="heading-using-interfaces-with-functions">USING INTERFACES WITH FUNCTIONS:</h2>
<p>The use of interfaces in functions generally refers to assigning types to the parameters and explicitly indicating the type of the return value.</p>
<h3 id="heading-interface-for-function-parameters">INTERFACE FOR FUNCTION PARAMETERS:</h3>
<p>To avoid repeating complex types for multiple variables/parameters, we can create an interface for the parameter of the function and use the interface as a type.</p>
<p>Take a look at the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Course {
  name: <span class="hljs-built_in">string</span>;
  price: <span class="hljs-built_in">number</span>;
  isFree: <span class="hljs-built_in">boolean</span>;
}

<span class="hljs-keyword">let</span> courses: Course[] = [];

<span class="hljs-keyword">const</span> addCourse = (course: Course): <span class="hljs-function"><span class="hljs-params">void</span> =&gt;</span> {
  courses.push(course);
};

addCourse({
  name: <span class="hljs-string">"Angular"</span>,
  price: <span class="hljs-number">100</span>,
  isFree: <span class="hljs-literal">true</span>,
});

<span class="hljs-built_in">console</span>.log(courses); <span class="hljs-comment">// prints [{name: "Angular", price: 100, isFree: true}]</span>
</code></pre>
<p>Like our previous examples, we have a <code>Course</code> interface with some properties. Additionally, we have an <code>addCourse</code> function that expects a parameter of type <code>Course</code>. Using <code>addCourse</code> we append the <code>course</code> parameter to <code>courses</code>, a variable that has a type of <code>Course[]</code> <em>(An array of elements with the type</em> <code>Course</code><em>)</em>.</p>
<p>When we use interface as a type for the parameter, we avoid writing the same and lengthy type structure over and over again as well as getting autocompletion when we make any operation on the parameter, as shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645273214887/I2VpVj_OJ.png" alt="image.png" /></p>
<h3 id="heading-interface-for-function-return-type">INTERFACE FOR FUNCTION RETURN TYPE:</h3>
<p>The interface can also be used as a function return type, as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Course {
  name: <span class="hljs-built_in">string</span>;
  price: <span class="hljs-built_in">number</span>;
  isFree: <span class="hljs-built_in">boolean</span>;
}

<span class="hljs-keyword">let</span> courses: Course[] = [];

<span class="hljs-keyword">const</span> addCourse = (course: Course): <span class="hljs-function"><span class="hljs-params">void</span> =&gt;</span> {
  course.name = course.name.toUpperCase();
  courses.push(course);
};

<span class="hljs-comment">// function with return type Course[] (Array of Course)</span>
<span class="hljs-keyword">const</span> getCourses = (): Course[] =&gt; {
  <span class="hljs-keyword">return</span> courses;
};

addCourse({
  name: <span class="hljs-string">"Angular"</span>,
  price: <span class="hljs-number">100</span>,
  isFree: <span class="hljs-literal">true</span>,
});

<span class="hljs-keyword">let</span> coursesArray = getCourses();
</code></pre>
<p>A new function called <code>getCourses</code> is added here to return the <code>courses</code> array, which is of type <code>Course[]</code>. This can be specified as a return type.</p>
<p>If you don't explicitly specify the return type of <code>getCourses</code>, TypeScript will infer it as a <code>Course[]</code> as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645273488996/c8X0WIYfF.png" alt="image.png" /></p>
<h2 id="heading-using-interfaces-with-classes">USING INTERFACES WITH CLASSES:</h2>
<p>In our last blog, <a target="_blank" href="https://blog.wajeshubham.in/classes-in-typescript">Classes in typescript,</a> we took a deep dive into class concepts.</p>
<p>We will now look at how we can make classes more powerful by using <code>interfaces</code>.</p>
<h3 id="heading-class-implementing-interface">CLASS IMPLEMENTING INTERFACE:</h3>
<p>In TypeScript, a class can implement interfaces to enforce particular contracts (similar to languages such as Java and C#).</p>
<p>To implement an interface inside a class, we use the <code>implements</code> (with s) keyword after the class name and then specify the interface name. Check out the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> CourseInterface {
  name: <span class="hljs-built_in">string</span>;
  price: <span class="hljs-built_in">number</span>;
  onPurchase: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;
}

<span class="hljs-keyword">class</span> Course <span class="hljs-keyword">implements</span> CourseInterface {
  name: <span class="hljs-built_in">string</span>;
  price: <span class="hljs-built_in">number</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span>, price: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.price = price;
  }

  onPurchase() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`You have purchased <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
  }
}
</code></pre>
<p>As you can see, there is an interface named <code>CourseInterface</code> that has three properties, which are <code>name</code> of type <code>string</code>, <code>price</code> of type <code>number</code>, and <code>onPurchase</code>, a function that accepts no parameters and returns <code>void</code>.</p>
<p>There is also a class named <code>Course</code> that implements <code>CourseInterface</code>. Thus, it is necessary for a <code>Course</code> class to implement the same <strong>mandatory properties and methods</strong> that the <code>CourseInterface</code> possesses. If we miss any one of these <strong>mandatory properties</strong>, we will receive the following compilation error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645362089365/8yDrCR2Ji.png" alt="image.png" /></p>
<p>The error reads, <code>Property 'onPurchase' is missing in type 'Course', but it is required in type 'CourseInterface'</code>. Therefore, we must either add the <code>onPurchase</code> method or make that property optional.</p>
<blockquote>
<p>The <strong>interface</strong> is somewhat similar to the <strong>abstract class</strong>, but there are some differences. We'll discuss the <strong>difference between an abstract class and an interface</strong> in an upcoming post here.</p>
</blockquote>
<h3 id="heading-implementing-multiple-interfaces">IMPLEMENTING MULTIPLE INTERFACES:</h3>
<p>Classes can implement multiple interfaces at once.</p>
<p>Let's take an example to understand this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Shape {
  getArea(): <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">interface</span> Color {
  color: <span class="hljs-built_in">string</span>;
  getColor(): <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">class</span> Circle <span class="hljs-keyword">implements</span> Shape, Color {
  <span class="hljs-keyword">private</span> radius: <span class="hljs-built_in">number</span>;
  color: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">rad: <span class="hljs-built_in">number</span>, clr: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.radius = rad;
    <span class="hljs-built_in">this</span>.color = clr;
  }

  getArea(): <span class="hljs-built_in">number</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.PI * <span class="hljs-built_in">this</span>.radius * <span class="hljs-built_in">this</span>.radius;
  }

  getColor(): <span class="hljs-built_in">string</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.color;
  }
}

<span class="hljs-keyword">const</span> circle = <span class="hljs-keyword">new</span> Circle(<span class="hljs-number">5</span>, <span class="hljs-string">"red"</span>);
<span class="hljs-built_in">console</span>.log(circle.getArea()); <span class="hljs-comment">// prints 78.5398</span>
<span class="hljs-built_in">console</span>.log(circle.getColor()); <span class="hljs-comment">// prints red</span>
</code></pre>
<p>The example above shows two interfaces named <code>Shape</code> and <code>Color</code>, each of which has certain properties with their types. Additionally, we have a class called <code>Circle</code> which implements these two interfaces.</p>
<p>If any one of the <strong>mandatory properties</strong> of any one of the interfaces is missing, we will get the following compilation error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645363466789/YFezEpblh.png" alt="image.png" /></p>
<p>These interfaces can also be used to implement other classes as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Shape {
  getArea(): <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">interface</span> Color {
  color: <span class="hljs-built_in">string</span>;
  getColor(): <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">class</span> Rectangle <span class="hljs-keyword">implements</span> Shape, Color {
  <span class="hljs-keyword">private</span> length: <span class="hljs-built_in">number</span>;
  <span class="hljs-keyword">private</span> width: <span class="hljs-built_in">number</span>;
  color: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">l: <span class="hljs-built_in">number</span>, w: <span class="hljs-built_in">number</span>, clr: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.length = l;
    <span class="hljs-built_in">this</span>.width = w;
    <span class="hljs-built_in">this</span>.color = clr;
  }

  getArea(): <span class="hljs-built_in">number</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.length * <span class="hljs-built_in">this</span>.width;
  }

  getColor(): <span class="hljs-built_in">string</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.color;
  }
}

<span class="hljs-keyword">const</span> rect = <span class="hljs-keyword">new</span> Rectangle(<span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-string">"green"</span>);
<span class="hljs-built_in">console</span>.log(rect.getArea()); <span class="hljs-comment">// prints 200</span>
<span class="hljs-built_in">console</span>.log(rect.getColor()); <span class="hljs-comment">// prints green</span>
</code></pre>
<p>This allows us to add strict type checks and provide documentation in our code, which makes the development process more convenient and reliable.</p>
<h2 id="heading-interface-interface-inheritance">INTERFACE - INTERFACE INHERITANCE:</h2>
<p>Extending an <code>interface</code> essentially means inheriting it from another <code>interface</code>. Similar to class inheritance we can use the <code>extends</code> keyword to inherit an interface.</p>
<h3 id="heading-extending-an-interface">EXTENDING AN INTERFACE:</h3>
<p>Take a look at the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Animal {
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
  eat: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;
}

<span class="hljs-keyword">interface</span> Dog <span class="hljs-keyword">extends</span> Animal {
  breed: <span class="hljs-built_in">string</span>;
  bark: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;
}
</code></pre>
<p>The above code contains an interface called <code>Animal</code> and an interface called <code>Dog</code> which inherits <code>Animal</code>.</p>
<p>As a result, you can use an interface <code>Dog</code> to implement a class that must implement <code>Dog</code> as well as the <strong>mandatory properties/methods</strong> of the <code>Animal</code> interface.</p>
<p>Take a look at the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// example for interface inheritance</span>

<span class="hljs-keyword">interface</span> Animal {
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
  eat: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;
}

<span class="hljs-keyword">interface</span> Dog <span class="hljs-keyword">extends</span> Animal {
  breed: <span class="hljs-built_in">string</span>;
  bark: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;
}

<span class="hljs-keyword">class</span> Labrador <span class="hljs-keyword">implements</span> Dog {
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
  breed: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span>, age: <span class="hljs-built_in">number</span>, breed: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.age = age;
    <span class="hljs-built_in">this</span>.breed = breed;
  }
  bark() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Woof! Woof!"</span>);
  }
  eat() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Yum yum"</span>);
  }
}

<span class="hljs-keyword">const</span> labrador = <span class="hljs-keyword">new</span> Labrador(<span class="hljs-string">"Max"</span>, <span class="hljs-number">3</span>, <span class="hljs-string">"Labrador"</span>);
</code></pre>
<p>You will get a compilation error if you miss any of the <code>Animal</code> or <code>Dog</code> properties as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645366957335/Y05V9MfVQ.png" alt="image.png" /></p>
<p>In this case, we are missing the <code>eat</code> property, which is of type <code>() =&gt; void</code> in the <code>Animal</code> interface.</p>
<p>Also, <code>Animal</code> can still be used as a valid interface independently if required.</p>
<h3 id="heading-extending-multiple-interfaces">EXTENDING MULTIPLE INTERFACES:</h3>
<p>It is possible to extend more than one interface while inheriting. Here is an example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Species {
  family: <span class="hljs-built_in">string</span>;
  genus: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">interface</span> Animal {
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
  eat: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;
}

<span class="hljs-keyword">interface</span> Dog <span class="hljs-keyword">extends</span> Animal, Species {
  breed: <span class="hljs-built_in">string</span>;
  bark: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;
}
</code></pre>
<p>In this case, we have another interface called <code>Species</code> that is inherited by the <code>Dog</code> interface. In any class that implements a <code>Dog</code> interface, we now need to add all the <strong>mandatory</strong> <strong>properties</strong> of <code>Species</code>, <code>Animal</code>, and <code>Dog</code>.</p>
<h2 id="heading-difference-between-a-type-and-an-interface">DIFFERENCE BETWEEN A TYPE AND AN INTERFACE:</h2>
<h3 id="heading-use-case">USE CASE:</h3>
<p><code>interfaces</code> are a way to describe data shapes, such as objects. The <code>type</code> attribute defines the type of data, for example, union, primitive, intersection, tuple, any, or even object.</p>
<h3 id="heading-extends-andamp-implements">EXTENDS &amp; IMPLEMENTS:</h3>
<p>As we saw earlier in this blog, we can easily extend and implement <code>interfaces</code> with TypeScript. However, this is not possible with <code>types</code>. <strong>(Except that the type is representing an object)</strong></p>
<p>For example,</p>
<p>**The following code snippets are valid: **</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645700878648/GVECI3i0r.png" alt="image.png" /></p>
<p><strong>The following code snippets are invalid:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645700576519/Pru4DR8zJ.png" alt="image.png" /></p>
<p>The error above occurs because <code>ABC</code> is a <code>union type</code>, not an <code>object</code> type</p>
<h3 id="heading-merging">MERGING</h3>
<p>When you create multiple interfaces with the same name and some common and some unique properties, TypeScript will merge all the properties and will <strong>NOT</strong> generate a compilation error as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Int1 {
  a: <span class="hljs-built_in">number</span>;
  b: <span class="hljs-built_in">number</span>;
  c: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">interface</span> Int1 {
  a: <span class="hljs-built_in">number</span>;
  b: <span class="hljs-built_in">number</span>;
  d: <span class="hljs-built_in">number</span>;
}

<span class="hljs-comment">// int1 should include a, b, c and d properties</span>
<span class="hljs-comment">// if you miss any mandatory property, you will get an error</span>
<span class="hljs-keyword">const</span> int1: Int1 = {
  a: <span class="hljs-number">1</span>,
  b: <span class="hljs-number">2</span>,
  c: <span class="hljs-number">3</span>,
  d: <span class="hljs-number">4</span>,
};

<span class="hljs-comment">// Compiles without an error</span>
</code></pre>
<p>However, with <code>types</code>, TypeScript will throw a compilation error because declaring two <code>types</code> with the same name is not allowed. Refer to the following image:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1645646759482/bqSUF-Eme.png" alt="image.png" /></p>
<h2 id="heading-difference-between-an-abstract-class-and-an-interface">DIFFERENCE BETWEEN AN ABSTRACT CLASS AND AN INTERFACE:</h2>
<p><strong>Interfaces:</strong></p>
<ul>
<li><p>Promote loose coupling <em>(class is dependent on an interface rather than a class for the implementation)</em></p>
</li>
<li><p>We can implement more than one interface in a class.</p>
</li>
<li><p>Set up a contract between different classes <em>(the syntax/structure for classes to follow)</em></p>
</li>
<li><p>Serve as a “gatekeeper” to a function <em>(function can enforce the contract)</em></p>
</li>
<li><p>Work best when we have very different objects that we want to work with together.</p>
</li>
</ul>
<p><strong>Abstract classes:</strong></p>
<ul>
<li><p>Strongly couple classes together <em>(class is dependent on another class)</em></p>
</li>
<li><p>We can't inherit more than one abstract class.</p>
</li>
<li><p>Set up a contract between different classes <em>(the syntax/structure for classes to follow)</em></p>
</li>
<li><p>Work best when we are trying to build up the definition/blueprint of an object.</p>
</li>
</ul>
<h2 id="heading-conclusion">CONCLUSION:</h2>
<ul>
<li><p>In this article, we have written multiple TypeScript interfaces to represent various data structures, discovered how we can use different interfaces together as building blocks to create powerful types, and learned about the differences between normal type declarations and interfaces.</p>
</li>
<li><p>When should we use <strong>classes and interfaces</strong>? If you want to create and pass a type-checked class object, you should use TypeScript classes. If you need to work without creating an object, an interface is best for you.</p>
</li>
<li><p>In the last two articles, we opened two useful approaches: blueprints (classes) and contracts (interfaces). You can use both of them together or just one. It is up to you.</p>
</li>
<li><p>You can now start writing interfaces for data structures in your codebase, allowing you to have type-safe code as well as documentation.</p>
</li>
</ul>
<p>Make sure to subscribe to our newsletter on <a target="_blank" href="https://blog.wajeshubham.in/">https://blog.wajeshubham.in/</a> and never miss any upcoming articles related to TypeScript and programming just like this one.</p>
<p>I hope this post will help you in your journey. Keep learning!</p>
<p>My <a target="_blank" href="https://wajeshubham.in"><strong><em>Website</em></strong></a>, connect with me on <a target="_blank" href="https://www.linkedin.com/in/shubham-waje/">LinkedIn</a> and <a target="_blank" href="https://github.com/wajeshubham">GitHub</a></p>
]]></content:encoded></item><item><title><![CDATA[Classes in TypeScript]]></title><description><![CDATA[Looking back to our last article, we covered Functions in TypeScript which gave us an idea about how Functions work, are structured and are implemented in TypeScript.
In this article, we will discuss the syntax of creating classes, the different feat...]]></description><link>https://blog.wajeshubham.in/classes-in-typescript</link><guid isPermaLink="true">https://blog.wajeshubham.in/classes-in-typescript</guid><category><![CDATA[classes]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Shubham Waje]]></dc:creator><pubDate>Mon, 23 Jan 2023 19:53:19 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1674503520032/eefd1a6f-eea6-42d5-a8cd-1ae11c2467f3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Looking back to our last article, we covered <strong>Functions in TypeScript</strong> which gave us an idea about how Functions work, are structured and are implemented in TypeScript.</p>
<p>In this article, we will discuss the syntax of creating classes, the different features available, how classes are treated during compile-time type-check, access modifiers, shorthand initialization, how Getters and Setters work, static properties/methods, abstract class, and Singleton pattern.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644259092142/fq7h-XChg.png" alt="class.png" /></p>
<h2 id="heading-what-is-a-class">WHAT IS A CLASS?</h2>
<blockquote>
<p><strong>Classes are a common abstraction used in object-oriented programming (OOP) languages to describe data structures known as objects. These objects may contain an initial state and implement behaviors bound to that particular object instance.</strong></p>
</blockquote>
<h2 id="heading-what-typescript-adds">WHAT TYPESCRIPT ADDS?</h2>
<blockquote>
<p><strong>In 2015, ECMAScript 6 introduced a new syntax to JavaScript to create classes that internally use the prototype features of the language.</strong></p>
<p><strong>TypeScript has full support for that syntax and also adds features on top of it, like member visibility, abstract classes, generic classes, arrow function methods, access modifiers, and a few others.</strong></p>
</blockquote>
<h2 id="heading-syntax-declaration-amp-instance-creation">SYNTAX, DECLARATION &amp; INSTANCE CREATION:</h2>
<p>The syntax is mostly the same used to create classes with JavaScript. But there are some distinguishing features available in TypeScript.</p>
<h3 id="heading-create-a-class">CREATE A CLASS:</h3>
<p>You can create a class declaration by using the <code>class</code> keyword, followed by the class name and then a <code>{}</code> pair block, as shown in the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {

}
</code></pre>
<h3 id="heading-create-an-instance-using-new-keyword">CREATE AN INSTANCE USING <code>new</code> KEYWORD:</h3>
<p>The following snippet creates a new class named <code>Course</code>. You can then create a new instance of the <code>Course</code> class using the <code>new</code> keyword followed by the name of your class and an empty parameter list, as shown below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {

}

<span class="hljs-keyword">const</span> courseInstance = <span class="hljs-keyword">new</span> Course();
</code></pre>
<p>You can think of the <code>Course</code> class as a blueprint for creating objects and the <code>courseInstance</code> as one of those objects.</p>
<h3 id="heading-type-of-the-created-instance">TYPE OF THE CREATED INSTANCE:</h3>
<p>As you hover over the <code>courseInstance</code> variable, which is an instance of the class <code>Course</code>, you will see that TypeScript has inferred the type of the variable as <code>Course</code>.:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644779688881/o1A4c61Np.png" alt="image.png" /></p>
<p>So, the class can also be considered as a <code>type</code> in TypeScript.</p>
<h2 id="heading-constructor-function-amp-class-properties"><code>constructor</code> FUNCTION &amp; CLASS PROPERTIES:</h2>
<p>Most of the time, when working with classes, you will need to create a <code>constructor</code> function. A <code>constructor</code> is a method that runs every time a new instance of a class is created (<strong>Not when you declare a class</strong>). It can be used to initialize values/fields in the class.</p>
<p>A class can hold variables called properties which can be initialized inside a <code>constructor</code> function as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {
  title: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">n: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.title = n;
  }
}
</code></pre>
<p>Here, we are declaring a <code>title</code> variable/property of type <code>string</code> and initialize it within the constructor function.</p>
<p>When the constructor accepts a parameter, we need to pass it when creating an instance. The compilation error we will receive if we don't pass is as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644300772888/gWA1mkTLv.png" alt="image.png" /></p>
<p>The <code>Course</code> class is accepting a variable of type <code>string</code> which is mandatory. Hence, it must be passed when creating an instance as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {
  title: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">n: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.title = n;
  }
}

<span class="hljs-keyword">const</span> courseInstance = <span class="hljs-keyword">new</span> Course(<span class="hljs-string">"Typescript"</span>);
</code></pre>
<p>Now that <code>courseInstance</code> represents an instance of the class <code>Course</code>, you can access fields, methods, and properties of the class <code>Course</code> via this variable as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {
  title: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">n: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.title = n;
  }
}

<span class="hljs-keyword">const</span> courseInstance = <span class="hljs-keyword">new</span> Course(<span class="hljs-string">"Typescript"</span>);

<span class="hljs-built_in">console</span>.log(courseInstance.title); <span class="hljs-comment">// This will print Typescript</span>
</code></pre>
<h2 id="heading-class-methods-amp-this-keyword">CLASS METHODS &amp; <code>this</code> KEYWORD:</h2>
<p>Similar to properties, the class also can hold methods that are nothing but functions declared inside a class.</p>
<p>Let's take an example to understand the method:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {
  title: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">n: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.title = n;
  }

  describe() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`This is a <span class="hljs-subst">${<span class="hljs-built_in">this</span>.title}</span> course`</span>);
  }
}
</code></pre>
<p>In the above code snippet, we are declaring a <code>describe</code> method inside our <code>Course</code> class which is not accepting any parameters.</p>
<p>Inside it, we are printing a string <code>This is a ${this.title} course</code>. Here, the <code>this</code> keyword refers to the concrete instance of <code>Course</code> <em>(</em><code>courseInstance</code>). If you only specified <code>title</code> then it will throw a compilation error as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644300811764/poQz8sB40.png" alt="image.png" /></p>
<p>Thus, if you want to access any property or method of the <code>Course</code> class, you have to use the <code>this</code> keyword.</p>
<p>Now, let's call <code>describe</code> and see what we get in the console.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {
  title: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">n: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.title = n;
  }

  describe() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`This is a <span class="hljs-subst">${<span class="hljs-built_in">this</span>.title}</span> course`</span>);
  }
}

<span class="hljs-keyword">const</span> courseInstance = <span class="hljs-keyword">new</span> Course(<span class="hljs-string">"TypeScript"</span>);

courseInstance.describe();
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644302544337/-O4Um-ZbC.png" alt="image.png" /></p>
<h2 id="heading-inheritance">INHERITANCE:</h2>
<h3 id="heading-what-is-inheritance">WHAT IS INHERITANCE?</h3>
<ul>
<li><p><strong>Inheritance is an aspect of OOPs languages, which provides the ability of a program to create a new class from an existing class. It is a mechanism that acquires the properties and behaviors of a class from another class.</strong></p>
</li>
<li><p><strong>The class whose members are inherited is called the base class, and the class that inherits those members is called the child class.</strong></p>
</li>
</ul>
<h3 id="heading-extends-keyword"><code>extends</code> KEYWORD:</h3>
<p>To implement inheritance we have to use the <code>extends</code> keyword as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Animal {

}

<span class="hljs-keyword">class</span> Dog <span class="hljs-keyword">extends</span> Animal {

}
</code></pre>
<p>In the above code snippet, we are declaring a <strong>parent class</strong> <code>Animal</code> and a <strong>child class</strong> <code>Dog</code>. Using the <code>extends</code> keyword we are inheriting properties and methods of an <code>Animal</code> class inside a <code>Dog</code> class.</p>
<h3 id="heading-super-keyword"><code>super</code> KEYWORD:</h3>
<p>When you inherit any class, you must call the <code>super</code> method inside the constructor of the child class. <code>super</code> invokes the parent constructor and its values/parameters.</p>
<p>Let's take an example to understand this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Animal {
  name: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">n: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.name = n;
  }
}

<span class="hljs-keyword">class</span> Dog <span class="hljs-keyword">extends</span> Animal {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">dogName: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">super</span>(dogName);
  }
}

<span class="hljs-keyword">const</span> dog = <span class="hljs-keyword">new</span> Dog(<span class="hljs-string">"Tuffy"</span>);
</code></pre>
<p>A <strong>parent class</strong> <code>Animal</code> has a <code>name</code> property and its constructor also expects a parameter named <code>n</code> of type <code>string</code>.</p>
<p>Since the <code>Dog</code> class inherits the parent class <code>Animal</code>, whenever we create an instance of this class we must call the parent class <code>constructor</code> function. This is done by calling <code>super(dogName)</code>, which invokes the <code>constructor</code> of the <code>Animal</code> class with <code>dogName</code> as a parameter that the constructor of the <code>Animal</code> class expects.</p>
<p>A compilation error will occur if we do not pass any value inside <code>super()</code> because the <code>Animal</code> class expects a mandatory parameter <code>n</code> of type <code>string</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644525538806/HN8Af21TU.png" alt="image.png" /></p>
<p>In addition, since the <code>Animal</code> class expects a <code>string</code> type, we must pass <code>string</code> only if we pass a <code>number</code> we will get the following compilation error.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644525672284/4FTP0Uq8h.png" alt="image.png" /></p>
<p>In short, whenever you inherit any class you have to call <code>super</code> to invoke its constructor.</p>
<h2 id="heading-encapsulation-amp-access-modifiers">ENCAPSULATION &amp; ACCESS MODIFIERS:</h2>
<h3 id="heading-what-is-encapsulation">WHAT IS ENCAPSULATION?</h3>
<ul>
<li><p><strong>Encapsulation enables you to perform what’s called “data hiding”. It’s necessary to hide certain data so that it’s not changed accidentally or purposefully by other components or code in the program.</strong></p>
</li>
<li><p><strong>To achieve encapsulation, use the proper access modifiers combined with the proper member types to limit or expose the scope of data.</strong></p>
</li>
<li><p><strong>Access modifiers are markers on code that designate where that code can be used, and are as follows:</strong></p>
</li>
</ul>
<h3 id="heading-public-modifier"><code>public</code> MODIFIER:</h3>
<p><code>public</code> fields do not encapsulate since any calling code can modify the data at any time. If you declare a property/method without an access modifier, it is a <code>public</code> property/method.</p>
<p>Basically, <code>public</code> members are accessible everywhere without restrictions.</p>
<p>Let's take an example to understand more:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {
  <span class="hljs-keyword">public</span> title: <span class="hljs-built_in">string</span>; 

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">n: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.title = n;
  }
}

<span class="hljs-keyword">const</span> course = <span class="hljs-keyword">new</span> Course(<span class="hljs-string">'Angular'</span>);

<span class="hljs-built_in">console</span>.log(course.title); <span class="hljs-comment">// Prints: Angular</span>
</code></pre>
<p>All TypeScript members (properties and methods) are <code>public</code> by default, so you don't need to prefix them with the <code>public</code> keyword.</p>
<p>You can also modify the values of the <code>public</code> properties. Look at the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {
  <span class="hljs-keyword">public</span> title: <span class="hljs-built_in">string</span>; 

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">n: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.title = n;
  }
}

<span class="hljs-keyword">const</span> Course1 = <span class="hljs-keyword">new</span> Course(<span class="hljs-string">"Angular"</span>);

Course1.title = <span class="hljs-string">"TypeScript"</span>;

<span class="hljs-built_in">console</span>.log(Course1.title); <span class="hljs-comment">// Prints: TypeScript</span>
</code></pre>
<h3 id="heading-private-modifier"><code>private</code> MODIFIER:</h3>
<p>A <code>private</code> property/method cannot be accessed outside of its containing class. <code>private</code> properties and methods can only be accessed within the class.</p>
<p>Let's take an example to understand more:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {
  <span class="hljs-keyword">private</span> title: <span class="hljs-built_in">string</span>; 

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">n: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.title = n;
  }
}

<span class="hljs-keyword">const</span> course = <span class="hljs-keyword">new</span> Course(<span class="hljs-string">'Angular'</span>);

<span class="hljs-built_in">console</span>.log(course.title); <span class="hljs-comment">// Throws compilation error</span>
</code></pre>
<p>The above code has a <code>title</code> property which is a <code>private</code> property of the class <code>Course</code>.</p>
<p>Accessing it outside of the <code>Course</code> class will result in the following compilation error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644607584436/6CcbSYiyL8.png" alt="image.png" /></p>
<p>The child class does not even have access to <code>private</code> properties. Consider the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {
  <span class="hljs-keyword">private</span> title: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">n: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.title = n;
  }
}

<span class="hljs-keyword">class</span> PaidCourse <span class="hljs-keyword">extends</span> Course {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">super</span>(<span class="hljs-string">"Paid Course"</span>);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.title);
  }
}
</code></pre>
<p>In the above code, we have a <code>Course</code> class as a parent and a <code>PaidCourse</code> class as a child. We learned earlier that properties can be inherited from the parent class to the child class except for <code>private</code> properties. So the above code will result in the following compilation error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644607803970/VRLMUT2pd.png" alt="image.png" /></p>
<h3 id="heading-protected-modifier"><code>protected</code> MODIFIER:</h3>
<p>A <code>protected</code> member cannot be accessed outside of its containing class. Members that are <code>protected</code> can only be accessed within the class and its child classes.</p>
<p>In the above code, if we change the <code>title</code> property of the <code>Course</code> class from <code>private</code> to <code>protected</code>, the compilation error will be resolved. Check out the following image:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644608209885/uYM2ZFGGp.png" alt="image.png" /></p>
<p>You will, however, receive a compilation error if you try to access the <code>protected</code> <code>title</code> property through an instance of the <code>Course</code> class. See the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {
  <span class="hljs-keyword">protected</span> title: <span class="hljs-built_in">string</span>; <span class="hljs-comment">// only accessible within the class and child classes</span>

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">n: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.title = n;
  }
}

<span class="hljs-keyword">class</span> PaidCourse <span class="hljs-keyword">extends</span> Course {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">super</span>(<span class="hljs-string">"Paid Course"</span>);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">this</span>.title); <span class="hljs-comment">// prints "Paid Course" (valid line)</span>
  }
}

<span class="hljs-keyword">const</span> course = <span class="hljs-keyword">new</span> Course(<span class="hljs-string">"Another course"</span>); 

<span class="hljs-built_in">console</span>.log(course.title); <span class="hljs-comment">// throws error</span>
</code></pre>
<p>Because the <code>title</code> is a <code>protected</code> property, we cannot access it through the instance. We will receive the following compilation error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644608408719/MqBUlFGCu.png" alt="image.png" /></p>
<h3 id="heading-readonly-modifier"><code>readonly</code> MODIFIER:</h3>
<p>TypeScript supports <code>readonly</code> modifiers <strong>on the property level</strong> by using the <code>readonly</code> keyword. The <code>readonly</code> properties must be initialized at their declaration or in the constructor.</p>
<p>Take a look at the following code to understand this:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">class</span> Course {
  <span class="hljs-keyword">readonly</span> price: <span class="hljs-built_in">number</span>;
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">p: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">this</span>.price = p;
  }

  changePrice(p: <span class="hljs-built_in">number</span>) {
    <span class="hljs-built_in">this</span>.price = p; <span class="hljs-comment">// throws error because price is readonly</span>
  }
}

<span class="hljs-keyword">const</span> Course1 = <span class="hljs-keyword">new</span> Course(<span class="hljs-number">10</span>);

Course1.changePrice(<span class="hljs-number">20</span>);
</code></pre>
<p>We have a <code>readonly</code> <code>price</code> property in the above code, which can only be assigned once, inside the constructor function.</p>
<p>You will get a compilation error as follows if you try to change it anywhere else:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644608870265/r8yQXozRf.png" alt="image.png" /></p>
<h2 id="heading-shorthand-initialization">SHORTHAND INITIALIZATION:</h2>
<p>In previous examples, we declared properties first and then initialized them inside the <code>constructor</code> as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {
  title: <span class="hljs-built_in">string</span>;
  price: <span class="hljs-built_in">number</span>;
  ratings: <span class="hljs-built_in">number</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">title: <span class="hljs-built_in">string</span>, price: <span class="hljs-built_in">number</span>, ratings: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">this</span>.title = title;
    <span class="hljs-built_in">this</span>.price = price;
    <span class="hljs-built_in">this</span>.ratings = ratings;
  }
}
</code></pre>
<p>The above code first declares three properties and sets/assigns them inside a <code>constructor</code> function.</p>
<p>It is possible to write less and more readable code by simplifying and using a shortcut, as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Course {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">
    <span class="hljs-keyword">public</span> title: <span class="hljs-built_in">string</span>,
    <span class="hljs-keyword">public</span> price: <span class="hljs-built_in">number</span>,
    <span class="hljs-keyword">public</span> ratings: <span class="hljs-built_in">number</span>
  </span>) {}
}
</code></pre>
<p>In this case, Typescript will automatically generate those properties. Based on your requirements, you can use any other access modifier instead of <code>public</code>.</p>
<p>Unless you use access modifiers, TypeScript will just consider it as a parameter and not generate a property.</p>
<p>For example, in the above code, if we use <code>public</code> only for <code>title</code> and <code>amount</code>, and pass <code>ratings</code> without any access modifier, it will throw an error if you attempt to access <code>ratings</code> the following way:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644610017195/r-KsGPjRb.png" alt="image.png" /></p>
<p>So you have to use an access modifier to make <code>shorthand initialization</code> valid.</p>
<h2 id="heading-getters-amp-setters">GETTERS &amp; SETTERS:</h2>
<p><strong>Getters</strong> and <strong>Setters</strong> are nothing more than methods that provide access to an object's properties.</p>
<p>They allow us to hide implementation details from instance objects. Thus, we can do some operations inside getters and setters that are completely encapsulated.</p>
<ul>
<li><p><code>getter</code>: Use this method when you want to access any property of an object. A getter is also called an accessor.</p>
</li>
<li><p><code>setter</code>: Use this method when you want to change any property of an object. A setter is also known as a mutator.</p>
</li>
</ul>
<p>A getter method starts with the keyword <code>get</code> and a setter method starts with the keyword <code>set</code>.</p>
<p>Let's look at Getters and Setters one by one with examples:</p>
<h3 id="heading-getter-methods">GETTER METHODS:</h3>
<p>To understand the syntax and basic concept, let's take an example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Person {
  firstName: <span class="hljs-built_in">string</span>;
  lastName: <span class="hljs-built_in">string</span>;
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">f_name: <span class="hljs-built_in">string</span>, l_name: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.firstName = f_name;
    <span class="hljs-built_in">this</span>.lastName = l_name;
  }

  getFullName() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.firstName + <span class="hljs-string">" "</span> + <span class="hljs-built_in">this</span>.lastName;
  }
}

<span class="hljs-keyword">const</span> person = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"John"</span>, <span class="hljs-string">"Doe"</span>);
<span class="hljs-built_in">console</span>.log(person.getFullName()); <span class="hljs-comment">// prints "John Doe"</span>
</code></pre>
<p>In the above example, we have a class called <code>Person</code> that accepts <code>f_name</code> and <code>l_name</code> parameters and has <code>firstName</code> and <code>lastName</code> properties.</p>
<p>It also has a <code>method</code> called <code>getFullName()</code> that combines <code>firstName</code> and <code>lastName</code> to return a full name.</p>
<p>Instead of using the <code>getFullName</code> method, we can use getter as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Person {
  firstName: <span class="hljs-built_in">string</span>;
  lastName: <span class="hljs-built_in">string</span>;
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">f_name: <span class="hljs-built_in">string</span>, l_name: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.firstName = f_name;
    <span class="hljs-built_in">this</span>.lastName = l_name;
  }

  get fullName() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.firstName + <span class="hljs-string">" "</span> + <span class="hljs-built_in">this</span>.lastName;
  }
}

<span class="hljs-keyword">const</span> person = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"John"</span>, <span class="hljs-string">"Doe"</span>);

<span class="hljs-comment">// we dont execute getters</span>
<span class="hljs-built_in">console</span>.log(person.fullName); <span class="hljs-comment">// prints "John Doe"</span>
</code></pre>
<p>Using the <code>get</code> keyword, we declare a getter method. Notice that we don't execute or use <code>()</code> after <code>person.fullName</code> as TypeScript infers it as a <code>readonly</code> property. Hence, you cannot modify it. In doing so, you will receive the following error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644692283524/h5x6zuS-_.png" alt="image.png" /></p>
<p>In the first example, the method <code>getFullName</code> does the same thing as the getter method. However, the getter method is slightly simpler and it is easier to identify its purpose at a glance with its syntax.</p>
<h3 id="heading-setter-methods">SETTER METHODS:</h3>
<p>A setter method is used to mutate the value of a class member.</p>
<p>In our previous example, there was no way to replace a person's name other than to create a new object.</p>
<p>This provides us with class safety, but what if we need to change the <code>firstName</code>.</p>
<p>The setter method in TypeScript allows us to change the value of a property. <strong><em>(even if the value is</em></strong> <code>private</code> or <code>protected</code>)</p>
<p>To write a setter method, we use the keyword <code>set</code> before the method name.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Person {
  <span class="hljs-keyword">private</span> firstName: <span class="hljs-built_in">string</span>;
  <span class="hljs-keyword">private</span> lastName: <span class="hljs-built_in">string</span>;
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">f_name: <span class="hljs-built_in">string</span>, l_name: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.firstName = f_name;
    <span class="hljs-built_in">this</span>.lastName = l_name;
  }

  get fullName(): <span class="hljs-built_in">string</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.firstName}</span> <span class="hljs-subst">${<span class="hljs-built_in">this</span>.lastName}</span>`</span>;
  }

  set setFirstName(f_name: <span class="hljs-built_in">string</span>) {
    <span class="hljs-built_in">this</span>.firstName = f_name;
  }
}

<span class="hljs-keyword">const</span> person = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"John"</span>, <span class="hljs-string">"Doe"</span>);

<span class="hljs-comment">// Whatever value we assign to the setter, it will be passed to the setter as a parameter.</span>
person.setFirstName = <span class="hljs-string">"Rohan"</span>; <span class="hljs-comment">// Setting the firstName property</span>

<span class="hljs-built_in">console</span>.log(person.fullName); <span class="hljs-comment">// prints "Rohan Doe"</span>
</code></pre>
<p>We have a class called <code>Person</code> with two <code>private</code> properties called <code>firstName</code> and <code>lastName</code>. Additionally, there is a getter method to retrieve a person's full name and a setter method to change the <code>firstName</code>.</p>
<p><strong>IMPORTANT: Setter functions can take only one parameter. You will receive a compilation error if you try to pass more than one.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644693283920/LMGELfaFo.png" alt="image.png" /></p>
<h2 id="heading-static-properties-amp-methods">STATIC PROPERTIES &amp; METHODS:</h2>
<ul>
<li><p>Static members can be accessed without having the class instantiated. Of course, it depends on which access modifier you are using.</p>
</li>
<li><p>So <code>public</code> static members can be accessed directly from outside the class.</p>
</li>
<li><p><code>private</code> static members can only be used within the class, and</p>
</li>
<li><p><code>protected</code> members can be accessed by the class in which the member is defined as well as by its child classes.</p>
</li>
</ul>
<h3 id="heading-how-to-access-inside-a-class">HOW TO ACCESS INSIDE A CLASS:</h3>
<p>When working with the <code>static</code> properties/methods you have to use the class itself and not the instance of the class.</p>
<p>Check out the following code to see how to access them inside a class:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Mathematics {
  <span class="hljs-keyword">static</span> PI = <span class="hljs-number">3.14159</span>; <span class="hljs-comment">// static property</span>

  calculateCircumference(diameter: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">number</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.PI * diameter; <span class="hljs-comment">// this.PI is not accessible here because it is a static property</span>
  }
}
</code></pre>
<p>Here, <code>PI</code> is a <code>static</code> property and <code>calculateCircumference</code> is a normal method in the <code>Mathematics</code> class.</p>
<p>Therefore, if you try to access it inside of a class method by using the <code>this</code> keyword, you will receive an error because <code>PI</code> is <strong>NOT</strong> a class property. Rather, it is a <code>static</code> property.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644746104710/Ck88BXYv8.png" alt="image.png" /></p>
<p>To remove the error, we need to access the <code>static</code> property using the class name:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Mathematics {
  <span class="hljs-keyword">static</span> PI = <span class="hljs-number">3.14159</span>; <span class="hljs-comment">// static property</span>

  calculateCircumference(diameter: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">number</span> {
    <span class="hljs-keyword">return</span> Mathematics.PI * diameter;
  }
}
</code></pre>
<p><strong>NOTE: You can only use the</strong> <code>this</code> keyword inside a <code>static</code> method if you want to access the <code>static</code> property. Therefore, if you make <code>calculateCircumference</code> a <code>static</code> method then <code>this.PI</code> would be valid:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644746278545/mMG--PMMy.png" alt="image.png" /></p>
<h3 id="heading-how-to-access-outside-a-class">HOW TO ACCESS OUTSIDE A CLASS:</h3>
<p>Check out the following code to see how to access them outside a class:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Mathematics {
  <span class="hljs-keyword">static</span> PI = <span class="hljs-number">3.14159</span>; <span class="hljs-comment">// static property</span>

  <span class="hljs-comment">// static method</span>
  <span class="hljs-keyword">static</span> calculateCircumference(diameter: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">number</span> {
    <span class="hljs-keyword">return</span> Mathematics.PI * diameter;
  }
}

<span class="hljs-keyword">let</span> newMath = <span class="hljs-keyword">new</span> Mathematics();

<span class="hljs-built_in">console</span>.log(newMath.PI); <span class="hljs-comment">// This will throw an error</span>
<span class="hljs-built_in">console</span>.log(newMath.calculateCircumference(<span class="hljs-number">10</span>)); <span class="hljs-comment">// This will throw an error</span>

<span class="hljs-built_in">console</span>.log(Mathematics.PI); <span class="hljs-comment">// returns 3.14159</span>
<span class="hljs-built_in">console</span>.log(Mathematics.calculateCircumference(<span class="hljs-number">10</span>)); <span class="hljs-comment">// returns 31.4159</span>
</code></pre>
<p>If you try to access <code>static</code> property <code>PI</code> or <code>static</code> method <code>calculateCircumference</code> using <code>newMath</code> in the above code, you will get the following compilation error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644745530942/rjUUiAQyS.png" alt="image.png" /></p>
<p>In addition, TypeScript also detects that the <code>PI</code> and <code>calculateCircumference</code> are static properties and methods respectively and asks <code>"Did you mean to access the static member 'Mathematics.calculateCircumference' instead?"</code>.</p>
<h3 id="heading-inbuilt-math-class">INBUILT <code>Math</code> CLASS:</h3>
<ul>
<li><p>TypeScript's <code>Math</code> class provides no. of properties and methods for performing mathematical operations.</p>
</li>
<li><p><code>Math</code> is not a constructor and all the properties and methods of <code>Math</code> are <code>static</code>.</p>
</li>
</ul>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mathTest</span>(<span class="hljs-params">num: <span class="hljs-built_in">number</span></span>): <span class="hljs-title">void</span> </span>{
  <span class="hljs-keyword">var</span> squareRoot = <span class="hljs-built_in">Math</span>.sqrt(num); <span class="hljs-comment">// sqrt is a static method of Math</span>
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Random Number:  "</span> + num); <span class="hljs-comment">// logs random number</span>
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Square root:  "</span> + squareRoot); <span class="hljs-comment">// logs Square root of random number</span>
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"PI value: "</span>, <span class="hljs-built_in">Math</span>.PI); <span class="hljs-comment">// PI is a static property of Math</span>
}
<span class="hljs-keyword">var</span> randomNum: <span class="hljs-built_in">number</span> = <span class="hljs-built_in">Math</span>.random(); <span class="hljs-comment">// random is a static method of Math</span>
mathTest(randomNum);
</code></pre>
<h2 id="heading-abstraction-amp-abstract-class">ABSTRACTION &amp; ABSTRACT CLASS:</h2>
<ul>
<li><p><strong>Abstract classes can have implementation details for their members. To declare an abstract class, we can use the</strong> <code>abstract</code> keyword. We can also use the <code>abstract</code> keyword for methods to declare <code>abstract methods</code>, which are implemented by classes that derive from an abstract class.</p>
</li>
<li><p><strong>In short abstract classes are classes that have a partial implementation of a class from which other classes can be derived. It's a blueprint for classes.</strong></p>
</li>
<li><p><strong>They can’t be instantiated directly.</strong></p>
</li>
</ul>
<h3 id="heading-syntax-and-abstract-methods">SYNTAX AND ABSTRACT METHODS:</h3>
<p>Let's take an example to understand the syntax and implementation:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> Person {
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span>, age: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.age = age;
  }
  <span class="hljs-keyword">abstract</span> getName(): <span class="hljs-built_in">string</span>;
  <span class="hljs-keyword">abstract</span> getAge(): <span class="hljs-built_in">number</span>;
}
</code></pre>
<p>In the above code, we have declared a <code>Person</code> class prefixed with the <code>abstract</code> keyword which means it is an abstract class.</p>
<p>We have <code>name</code> and <code>age</code> as properties for the <code>Person</code> class. It also has the <code>abstract</code> methods <code>getName</code> and <code>getAge</code>. But if you see these methods don't have implementations in them we have just declared them with their return type.</p>
<p>Because abstract methods don’t contain implementations of the method. It’s up to the child classes that inherit the abstract class to implement the method listed. They may also, optionally, include access modifiers.</p>
<h3 id="heading-inherit-abstract-class">INHERIT ABSTRACT CLASS:</h3>
<p>Let's inherit the above class:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> Person {
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span>, age: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.age = age;
  }
  <span class="hljs-keyword">abstract</span> getName(): <span class="hljs-built_in">string</span>;
  <span class="hljs-keyword">abstract</span> getAge(): <span class="hljs-built_in">number</span>;
}


<span class="hljs-keyword">class</span> Employee <span class="hljs-keyword">extends</span> Person{
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span>, age: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">super</span>(name, age);
  }
  getName() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.name;
  }
  getAge() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.age;
  }
}
</code></pre>
<p>As we can see, in the <code>Person</code> class the abstract methods only have signatures in them. The actual implementation of the methods is in the <code>Employee</code> class, which extends the <code>Person</code> class.</p>
<p>If you miss any one of the abstract methods inside an <code>Employee</code> class you will get a compilation error as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644752217784/OSrVjsgLF.png" alt="image.png" /></p>
<p>TypeScript checks the method declaration and the return type of the method in the abstract class, so we must be implementing the abstract methods as it’s declared in the abstract class.</p>
<p>This means that in the example above, the <code>getName</code> method must take no parameters and must return a <code>string</code>. If you try to break those type checks you will get an error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644752459462/Pco7KAkX0.png" alt="image.png" /></p>
<p>Likewise, the <code>getAge</code> method must take no parameters and must return a <code>number</code>.</p>
<p>After the abstract methods have been implemented, we can call them normally like any other method as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> employee = <span class="hljs-keyword">new</span> Employee(<span class="hljs-string">"Jane"</span>, <span class="hljs-number">20</span>);
<span class="hljs-built_in">console</span>.log(employee.getName()); <span class="hljs-comment">// returns "Jane"</span>
<span class="hljs-built_in">console</span>.log(employee.getAge()); <span class="hljs-comment">// returns 20</span>
</code></pre>
<h2 id="heading-singleton-pattern">SINGLETON PATTERN:</h2>
<ul>
<li><p><strong>Singleton is a creational design pattern, which ensures that only one object of its kind exists and provides a single point of access to it for any other code.</strong></p>
</li>
<li><p><strong>It is a way to structure your code so that you can’t have more than one instance of your logic, ever.</strong></p>
</li>
</ul>
<h3 id="heading-singleton-class-in-typescript">SINGLETON CLASS IN TYPESCRIPT:</h3>
<p>We can use access modifiers on TypeScript constructors, so we can now create singletons as we do in other languages.</p>
<p>A singleton class's constructor is <code>private</code>, which means it cannot be used outside of the class. Therefore, we can't create an instance of that class with the <code>new</code> keyword.</p>
<p>To understand this let's create a singleton class:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">class</span> SingletonClass {
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"SingletonClass created"</span>);
  }
}

<span class="hljs-keyword">const</span> singletonClass = <span class="hljs-keyword">new</span> SingletonClass(); <span class="hljs-comment">// throws error</span>
</code></pre>
<p>In the above code, we have a class called <code>SingletonClass</code>, which has a <code>private</code> <code>constructor</code>. So, when we try creating an instance from that class, we receive the following error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644778298243/7Pvva43EE.png" alt="image.png" /></p>
<p>The above error indicates that we can only access the constructor within the class itself.</p>
<p>To make it a singleton class, we need to create an instance within the class as follows:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> SingletonClass {
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> instance: SingletonClass;

  <span class="hljs-comment">// only accessible within the class</span>
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"SingletonClass created"</span>);
  }


  <span class="hljs-keyword">static</span> getInstance() {
    <span class="hljs-keyword">if</span> (SingletonClass.instance) {
      <span class="hljs-keyword">return</span> SingletonClass.instance;
    }
    SingletonClass.instance = <span class="hljs-keyword">new</span> SingletonClass();
    <span class="hljs-keyword">return</span> SingletonClass.instance;
  }
}

<span class="hljs-keyword">const</span> singletonClass = SingletonClass.getInstance(); <span class="hljs-comment">// creates a new instance</span>
</code></pre>
<p>The above code declares a <code>private</code> and <code>static</code> property named <code>instance</code> that is of type <code>SingletonClass</code>.</p>
<p>We have declared a <code>static</code> method <code>getInstance</code> that first checks if an instance of the class <code>SingletonClass</code> already exists or not. Upon success, it will return the same instance otherwise a new instance will be created.</p>
<p>Therefore, if you call <code>getInstance</code> multiple times, the constructor function will only be executed once, as shown in the following image:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644779278499/LljmhRrA_.png" alt="image.png" /></p>
<h3 id="heading-use-cases">USE CASES:</h3>
<ul>
<li><p>The purpose of the singleton class is to control object creation, limiting the number of objects to only one.</p>
</li>
<li><p>The singleton allows only one entry point to create a new instance of the class.</p>
</li>
<li><p>The use of singletons is often useful when we need to control resources, such as database connections or sockets.</p>
</li>
</ul>
<h2 id="heading-conclusion">CONCLUSION:</h2>
<ul>
<li><p>TypeScript classes are even more powerful than JavaScript classes because they have access to the type system and new features such as member visibility, access modifiers, abstract classes, and much more.</p>
</li>
<li><p>In this way, you can deliver code that is type-safe, more reliable, and more representative of your business model.</p>
</li>
</ul>
<p>Make sure to subscribe to our newsletter on <a target="_blank" href="https://blog.wajeshubham.in/">https://blog.wajeshubham.in/</a> and never miss any upcoming articles related to TypeScript and programming just like this one.</p>
<p>I hope this post will help you in your journey. Keep learning!</p>
<p>My <a target="_blank" href="https://wajeshubham.in"><strong><em>Website</em></strong></a>, connect with me on <a target="_blank" href="https://www.linkedin.com/in/shubham-waje/">LinkedIn</a> and <a target="_blank" href="https://github.com/wajeshubham">GitHub</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Everyday types in TypeScript]]></title><description><![CDATA[As we explored in the last article, we have learned about TypeScript, why we use it, how it differs from JavaScript, how to install, configure, and run TypeScript, and some basic types in TypeScript.
In this article, we’ll learn in-depth about some o...]]></description><link>https://blog.wajeshubham.in/everyday-types-in-typescript</link><guid isPermaLink="true">https://blog.wajeshubham.in/everyday-types-in-typescript</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><category><![CDATA[Types]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Shubham Waje]]></dc:creator><pubDate>Sat, 14 Jan 2023 22:36:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1673735685407/3bf89fbf-c6f8-4862-a1bf-de74b21b9e9d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As we explored in the last <a target="_blank" href="https://blog.wajeshubham.in/introduction-to-typescript">article,</a> we have learned about TypeScript, why we use it, how it differs from JavaScript, how to install, configure, and run TypeScript, and some basic types in TypeScript.</p>
<p>In this article, we’ll learn in-depth about some of the most common types in TypeScript. They include <code>object</code>, <code>Array</code>, <code>Union types</code>, <code>enums</code>, <code>tuples</code>, <code>any</code> type, <code>Literal types</code>, and Type Aliases.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643195053682/FX3QVFNMV.png" alt="typescript-1.png" /></p>
<h2 id="heading-object-type"><code>object</code> TYPE:</h2>
<h3 id="heading-definition">DEFINITION:</h3>
<blockquote>
<p><strong>An</strong> <code>object</code> is a type of all <em>non-primitive</em> values (primitive values are undefined, null, booleans, numbers, and strings).</p>
</blockquote>
<p>To define an <code>object</code> type, we simply list its properties and their types. To understand this, take a look at the following examples mentioned below:</p>
<h3 id="heading-implicit-type">IMPLICIT TYPE:</h3>
<p>Firstly, open VS Code and create an <code>index.ts</code> file with the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> course = {
  name: <span class="hljs-string">"Learn typescript"</span>,
  price: <span class="hljs-number">20</span>,
};

<span class="hljs-built_in">console</span>.log(course);
</code></pre>
<p>As you hover over the course variable, you will see TypeScript has <strong>inferred</strong> the type of that variable.</p>
<p>Even though we haven't explicitly stated that the <code>course</code> variable will have <code>name</code> and <code>price</code> keys, the TypeScript type inference system handles writing these types.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643266544221/9VOceSCjv.png" alt="image.png" /></p>
<p>Visually, it looks like a JavaScript object. However, if you notice it has <code>;</code> at the end of the key-value pair, and the value of the key is nothing but a <code>type</code> of that particular key. The <code>name</code> key is of type <code>string</code> and the <code>price</code> key is of type <code>number</code>.</p>
<p>You will see autosuggestions from your IDE if you add a <code>.</code> after the <code>course</code> variable since the IDE is aware of the keys the <code>course</code> variable possesses.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643266705336/wo9eC0kNn.png" alt="image.png" /></p>
<p>The <strong>Compilation error</strong> with a descriptive message will appear if you attempt to access the key that does not exist in the course object. This is unlike JavaScript, which ignores the error without warning.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643266803807/thGQz78Oz.png" alt="image.png" /></p>
<h3 id="heading-explicit-type">EXPLICIT TYPE:</h3>
<p>Instead of having TypeScript infer the type for us, let's explicitly specify what type the <code>course</code> variable must have.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> course: {
  name: <span class="hljs-built_in">string</span>;
  price: <span class="hljs-built_in">number</span>;
  isPublished: <span class="hljs-built_in">boolean</span>;
} = {
  name: <span class="hljs-string">"Learn typescript"</span>,
  price: <span class="hljs-number">20</span>,
};

<span class="hljs-built_in">console</span>.log(course.name);
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643267602945/_WPOAH0g1.png" alt="image.png" /></p>
<p>We have assigned a boolean type with the key name <code>isPublished</code> to the <code>course</code> variable. Since we explicitly stated that the <code>course</code> variable must have <code>name</code>, <code>price</code>, and <code>isPublished</code> properties, TypeScript detects this as a compilation error since we are only passing the <code>name</code> and <code>price</code>.</p>
<p>Let's say you want to keep the <code>isPublished</code> property optional. In that case, you can add a <code>?</code> before <code>:</code> to make that property <strong>optional</strong> as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643267834183/A8B0WwV_j.png" alt="image.png" /></p>
<p>Furthermore, if you hover over the <code>isPublished</code> key, you will see that TypeScript has inferred its type as <code>boolean | undefined</code>. The reason is that <code>isPublished</code> is optional, and you may not pass any value to it. When that happens, you will receive an <code>undefined</code> value, and for that TypeScript warns you that the value of <code>isPublished</code> maybe <code>undefined</code>.</p>
<blockquote>
<p><code>isPublished</code> is called an optional property in the above example. In contrast, <code>boolean| undefined</code> is a <code>union type</code> which we will be exploring at great length in this blog.</p>
</blockquote>
<h3 id="heading-nested-object-types">NESTED <code>object</code> types:</h3>
<p>JavaScript also supports nested objects, which means objects can be nested within objects. Let's take a look at how we assign a type when dealing with such nested objects:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> course: {
  name: <span class="hljs-built_in">string</span>;
  price: <span class="hljs-built_in">number</span>;
  isPublished?: <span class="hljs-built_in">boolean</span>;
  student: {
    name: <span class="hljs-built_in">string</span>;
    age: <span class="hljs-built_in">number</span>;
  };
} = {
  name: <span class="hljs-string">"Learn typescript"</span>,
  price: <span class="hljs-number">20</span>,
  student: {
    name: <span class="hljs-string">"John"</span>,
    age: <span class="hljs-number">30</span>,
  },
};

<span class="hljs-built_in">console</span>.log(course);
</code></pre>
<p>In the above example, we have <code>course</code> which is an object, inside which we have the <code>student</code> key, which itself is another <code>object</code> with the <code>name</code> and <code>age</code> keys.</p>
<p>So now, if you try to access <code>student</code>, you will also get autosuggestions for the <code>student</code> object which is nested inside the <code>course</code> object.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643268711992/lbDXOFemq.png" alt="image.png" /></p>
<p>Also, typescript knows the type of values that we are getting in all the keys of the <code>course</code> variable so it can also suggest possible methods for a particular type of values:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643268804692/fgmD9ZMCX.png" alt="image.png" /></p>
<h2 id="heading-array-type"><code>Array</code> TYPE:</h2>
<h3 id="heading-definition-1">DEFINITION:</h3>
<blockquote>
<p><code>Array</code> refers to a special type of data type that can store multiple values of different types sequentially using a special syntax.</p>
</blockquote>
<h3 id="heading-shorthand-syntax-type">SHORTHAND SYNTAX <code>type[]</code>:</h3>
<p>Take a look at the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> course = {
  name: <span class="hljs-string">"Learn typescript"</span>,
  price: <span class="hljs-number">20</span>,
  tags: [<span class="hljs-string">"typescript"</span>, <span class="hljs-string">"javascript"</span>],
};

<span class="hljs-built_in">console</span>.log(course);
</code></pre>
<p>Now, when you hover over <code>tags</code>, you will see that it says <code>string[]</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643275604887/dz81bjXfIm.png" alt="image.png" /></p>
<p>It is a shorthand and widely used syntax when assigning a type to an array. A <code>string[]</code> notation implies that the array contains only <code>string</code> elements.</p>
<p>Since <code>"typescript"</code> and <code>"javascript"</code> are <code>strings</code>, it infers <code>tags</code> key as a <code>string[]</code> (array of strings).</p>
<h3 id="heading-generic-syntax-array">GENERIC SYNTAX <code>Array&lt;type&gt;</code>:</h3>
<p>Another way to specify a type for an array is to use generic syntax, such as:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> course: {
  name: <span class="hljs-built_in">string</span>;
  price: <span class="hljs-built_in">number</span>;
  tags: <span class="hljs-built_in">Array</span>&lt;<span class="hljs-built_in">string</span>&gt;; <span class="hljs-comment">// this is generic syntax Array&lt;type_of_elements&gt;</span>
} = {
  name: <span class="hljs-string">"Learn typescript"</span>,
  price: <span class="hljs-number">20</span>,
  tags: [<span class="hljs-string">"typescript"</span>, <span class="hljs-string">"javascript"</span>],
};

<span class="hljs-built_in">console</span>.log(course);
</code></pre>
<p>Here, we specify that <code>tags</code> is an <code>Array</code> that contains only <code>string</code> type elements.</p>
<p>The <code>&lt;&gt;</code> indicates that this is a <strong>Generic type</strong>, and we must specify the type of elements to include in this array. <em>(We will study Generic types in depth in future blogs)</em></p>
<p>The following error will occur if the element type is not provided:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643276116359/1f06evACW.png" alt="image.png" /></p>
<blockquote>
<p>TypeScript generally infers the type of an array with <strong>shorthand syntax</strong></p>
</blockquote>
<h3 id="heading-array-with-mixed-types"><code>Array</code> WITH MIXED TYPES:</h3>
<p>What if the array has elements of different types? For instance,</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> course = {
  name: <span class="hljs-string">"Learn typescript"</span>,
  price: <span class="hljs-number">20</span>,
  tags: [<span class="hljs-string">"typescript"</span>, <span class="hljs-string">"javascript"</span>, <span class="hljs-number">20</span>, <span class="hljs-number">10</span>],
};
</code></pre>
<p>Hovering over <code>tags</code> reveals its type as <code>(string | number)[]</code> <em>(Again,</em> <code>string | number</code> is a union type, which means the array includes elements which can be of type <code>string</code> or <code>number</code>).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643276227269/arAjVF7DO.png" alt="image.png" /></p>
<blockquote>
<p>We need something called <strong>type guards</strong> for handling <strong>union types</strong>. This is a bit advanced, so we will cover it in a later blog post.</p>
</blockquote>
<h3 id="heading-array-of-object"><code>Array</code> OF <code>object</code>:</h3>
<p>The types of objects that should be included in an array can be explicitly specified. This allows us to avoid runtime errors and speed up development.</p>
<p>To understand how to define a type for an array of specific objects, let's take an example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> course1 = {
  name: <span class="hljs-string">"Learn typescript"</span>,
  price: <span class="hljs-number">20</span>,
  tags: [<span class="hljs-string">"typescript"</span>, <span class="hljs-number">20</span>, <span class="hljs-number">10</span>],
};

<span class="hljs-keyword">const</span> course2 = {
  name: <span class="hljs-string">"Learn javascript"</span>,
  price: <span class="hljs-number">20</span>,
  tags: [<span class="hljs-string">"javascript"</span>, <span class="hljs-number">10</span>],
};

<span class="hljs-keyword">const</span> courses: {
  name: <span class="hljs-built_in">string</span>;
  price: <span class="hljs-built_in">number</span>;
  tags: (<span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span>)[];
}[] = [course1, course2];

<span class="hljs-built_in">console</span>.log(courses);
</code></pre>
<p>We have two objects here, <code>course1</code> and <code>course2</code>, whose type is <code>{ name: string; price: number; tags: (string | number)[]; }</code>.</p>
<p>Then we have another variable <code>courses</code> that contains a list of these two courses, so let's create an array with each element being of a type <code>{ name: string; price: number; tags: (string | number)[]; }</code></p>
<p>The type is now known, and we know that <code>courses</code> should be <code>Array</code> of type <code>{ name: string; price: number; tags: (string | number)[]; }</code></p>
<p>Therefore, we assigned <code>{ name: string; price: number; tags: (string | number)[]; }[]</code> as the type of <code>courses</code> variable.</p>
<p>As shown below, TypeScript will automatically infer the type for you if you don't explicitly mention it:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643277201228/-iWWrOUO9.png" alt="image.png" /></p>
<p>Because TypeScript knows what type of element the <code>courses</code> array has, you will get autosuggestions not only for <code>courses</code> but also for each element in the <code>courses</code> array when you perform any operation on it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643277328368/aIktQAZVi.png" alt="image.png" /></p>
<h2 id="heading-tuple-type"><code>tuple</code> TYPE:</h2>
<h3 id="heading-definition-2">DEFINITION:</h3>
<blockquote>
<p><strong>A</strong> <code>tuple</code> type is a type of <code>Array</code> that knows how many elements it contains, as well as the type of elements contained at specific positions.</p>
</blockquote>
<p>Here is how we can declare a variable as a tuple:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> course: [<span class="hljs-built_in">number</span>, <span class="hljs-built_in">string</span>] = [<span class="hljs-number">1</span>, <span class="hljs-string">"Typescript"</span>];
</code></pre>
<p>Here, we are saying that the course is an array of fixed length and must have the first element of type <code>number</code> and the second element of the type <code>string</code>.</p>
<p>If you try to replace the element at the index <code>0</code> which is of type <code>number</code> with a <code>string</code>, you will get a compilation error because we explicitly specified that the element at the index <code>0</code> must be a <code>number</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643355601047/QcZMvqc66.png" alt="image.png" /></p>
<h3 id="heading-exception-in-tuple">EXCEPTION IN <code>tuple</code>:</h3>
<p>A <code>tuple</code> should indeed be immutable, but it is still possible to <code>push</code> an element in it because TypeScript doesn't throw a compilation error when you call the <code>.push()</code> method.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643355878121/Wqnv-40eU.png" alt="image.png" /></p>
<p>However, if you attempt to reassign the variable with a different structure, you will receive the following compilation error:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643355992236/Aqer-o6YZ.png" alt="image.png" /></p>
<p>When reassigning, you need to follow the same structure as when assigning.</p>
<h3 id="heading-possible-use-case-of-tuple">POSSIBLE USE CASE OF <code>tuple</code>:</h3>
<p>If you need exactly <code>x</code> amount of values in an array, and you know the type of each element at a specific index, then you may want to consider using <code>tuple</code> type instead of an <code>Array</code> type, for more strictness.</p>
<h2 id="heading-enum-type"><code>enum</code> TYPE:</h2>
<h3 id="heading-definition-3">DEFINITION:</h3>
<blockquote>
<p><strong>Enums are one of the few features TypeScript has which is not a type-level extension of JavaScript.</strong></p>
<p><strong>By using enums, we can create sets of constants with names. You can create cases and documentation more easily by using enums.</strong></p>
</blockquote>
<h3 id="heading-numeric-enums">NUMERIC ENUMS:</h3>
<p>An enum can be defined using the <code>enum</code> keyword. Take a look at the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">enum</span> Role {
  ADMIN = <span class="hljs-number">1</span>,
  READ_ONLY,
  AUTHOR,
}

<span class="hljs-keyword">const</span> user: {
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
  role: Role;
} = {
  name: <span class="hljs-string">"Max"</span>,
  age: <span class="hljs-number">30</span>,
  role: Role.ADMIN,
};
</code></pre>
<p>We have a <code>numeric enum</code> where <code>ADMIN</code> is initialized with 1. From that point forward, all of the following members will be auto-incremented. Thus, <code>Role.ADMIN</code> has the value 1, <code>READ_ONLY</code> has 2, and <code>AUTHOR</code> has 3.</p>
<p>Once we define an <code>enum</code> type, in the above case its <code>Role</code>, we don't need to remember what the value of any particular role is, we can simply access enum variables with their names such as Role.ADMIN or Role.READ_ONLY or Role.AUTHOR.</p>
<p>You will also get autosuggestions from your IDE to do so as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643357300269/WX5Y5MrV8.png" alt="image.png" /></p>
<p>In addition, if you want to change values for the enum variable, you can do it in your <code>enum</code> type <code>Role</code>. You don't have to make that change everywhere in the code.</p>
<h3 id="heading-string-enums">STRING ENUMS:</h3>
<p>In the same way as <code>numeric enums</code>, enums can have strings as values. Here's an example:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">enum</span> Role {
  ADMIN = <span class="hljs-string">"admin"</span>,
  READ_ONLY = <span class="hljs-string">"read_only"</span>,
  AUTHOR = <span class="hljs-string">"author"</span>,
}
</code></pre>
<p>As the logic remains the same, but in <code>numeric enums</code> you will get <code>1</code> in return from <code>Role.ADMIN</code>, as in <code>string enums</code> you will get <code>"admin"</code>.</p>
<p>It is up to you what you want to assign to each enum.</p>
<h3 id="heading-heterogeneous-enums">HETEROGENEOUS ENUMS:</h3>
<p>Similarly, you can assign mixed types of values to enums as follows:</p>
<pre><code class="lang-ts"><span class="hljs-built_in">enum</span> Role {
  ADMIN = <span class="hljs-number">1</span>
  READ_ONLY = <span class="hljs-string">"read_only"</span>,
  AUTHOR = <span class="hljs-number">3</span>,
}
</code></pre>
<p>You get the point!</p>
<h2 id="heading-any-type"><code>any</code> TYPE:</h2>
<h3 id="heading-definition-4">DEFINITION:</h3>
<blockquote>
<p><strong>When a value is of type</strong> <code>any</code>, you can access any property of it, call it like a <code>function</code>, assign it to a value of any type, or pretty much anything else as long as it's syntactically legal.</p>
</blockquote>
<h3 id="heading-why-not-use-any">WHY NOT USE <code>any</code>:</h3>
<p>While <code>any</code> type is flexible, it loses all the advantages that TypeScript offers. As a result, it provides the same experience as vanilla JavaScript, thus eliminating the need for TypeScript.</p>
<p>Take a look at the following code:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">let</span> person: <span class="hljs-built_in">any</span> = {
  name: <span class="hljs-string">"John"</span>,
  age: <span class="hljs-number">30</span>,
};

<span class="hljs-built_in">console</span>.log(person.canWalk())
</code></pre>
<p>In the above example, we are calling the <code>canWalk()</code> function, which does not exist in the <code>person</code> variable. However, TypeScript is simply ignoring everything about that particular variable, so we aren't getting any compilation errors.</p>
<p>There is no autocompletion for this variable, which is another downside.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643367817721/cIrRYxxdk.png" alt="image.png" /></p>
<p>This is a disadvantage of using <code>any</code> type and you should avoid using <code>any</code> unless you don't know the type of the variable or parameter.</p>
<h3 id="heading-use-case-of-any">USE CASE OF <code>any</code>:</h3>
<ul>
<li><p>When there are no other options, and no type definitions are available for the piece of code you're working on, choose the <code>any</code> type.</p>
</li>
<li><p><code>any</code> has some practical use cases. For example, if you are getting a response from an API call and you don't know the structure of the response, then you can use <code>any</code> to disable the type-checking for the response object.</p>
</li>
<li><p><strong>However, if you know the type, be explicit about it</strong>.</p>
</li>
</ul>
<h2 id="heading-union-types">UNION TYPES:</h2>
<h3 id="heading-definition-5">DEFINITION:</h3>
<blockquote>
<p><strong>TypeScript’s type system allows you to build new types out of existing ones using a large variety of operators. We can create new custom types by combining some of the core types.</strong></p>
</blockquote>
<h3 id="heading-syntax">SYNTAX:</h3>
<p>The <code>|</code> operator enables us to combine different types and create a new one. In the previous topics, we used this concept:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> strOrNumArray: (<span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span>)[] = [];
</code></pre>
<p>In the above example, we are saying that the <code>strOrNumArray</code> could contain elements of type either <code>string</code> or <code>number</code></p>
<p>So, you won't get a compilation error if you insert elements of type 'number' or 'string'. However, adding a <code>boolean</code> type will result in the compilation error as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643373875571/X31ZYfRB7.png" alt="image.png" /></p>
<p>The above code can be made valid by adding another type <code>boolean</code> after <code>string</code> and <code>number</code> to make an array that has the possibility of <code>string</code>, <code>number</code>, and <code>boolean</code>, as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643374129901/ZZb5UCxxw.png" alt="image.png" /></p>
<h3 id="heading-handle-compilation-errors-using-type-guards">HANDLE COMPILATION ERRORS USING TYPE GUARDS:</h3>
<p>When you use union types, you will get a compilation error if the operation is only valid for one of the types you specified.</p>
<p>Let's see an example to understand this. take a look at the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> combineStrOrNum = <span class="hljs-function">(<span class="hljs-params">param1: <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span>, param2: <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span></span>) =&gt;</span> {
  <span class="hljs-keyword">let</span> result = param1 + param2; <span class="hljs-comment">// compilation error here</span>
  <span class="hljs-keyword">return</span> result;
};
</code></pre>
<p>In the above example, by stating that the <code>param1</code> and <code>param2</code> are both of type <code>string | number</code>, we mean that there may be cases when you pass <code>param1</code> as <code>number</code> and <code>param2</code> as <code>string</code>, and as we saw in our blog on Introduction to TypeScript, using <code>+</code> between types <code>string</code> and <code>number</code> can lead to unexpected behavior.</p>
<p>So, typescript complains that this expression can yield unexpected value.</p>
<p>We can handle this with type guards, which are available in JavaScript as well. Look at the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> combineStrOrNum = <span class="hljs-function">(<span class="hljs-params">param1: <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span>, param2: <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span></span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> param1 === <span class="hljs-string">"number"</span> &amp;&amp; <span class="hljs-keyword">typeof</span> param2 === <span class="hljs-string">"number"</span>) {
    <span class="hljs-built_in">console</span>.log(param1 + param2); <span class="hljs-comment">// return sum of 2 numbers</span>
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> param1 === <span class="hljs-string">"string"</span> &amp;&amp; <span class="hljs-keyword">typeof</span> param2 === <span class="hljs-string">"string"</span>) {
    <span class="hljs-built_in">console</span>.log(param1 + <span class="hljs-string">" "</span> + param2); <span class="hljs-comment">// return concatenation of 2 strings</span>
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Mixed types can not be added"</span>); <span class="hljs-comment">// return error message</span>
  }
};

combineStrOrNum(<span class="hljs-string">"Hello"</span>, <span class="hljs-string">"World"</span>); <span class="hljs-comment">// Hello World</span>
combineStrOrNum(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>); <span class="hljs-comment">// 3</span>
combineStrOrNum(<span class="hljs-string">"Hello"</span>, <span class="hljs-number">2</span>); <span class="hljs-comment">// "Mixed types can not be added" (unexpected behavior)</span>
</code></pre>
<p>Here, the <code>typeof</code> keyword indicates the type of a particular variable value.</p>
<p>When the type of <code>param1</code> and <code>param2</code> is <code>string</code>, then only we want to concatenate them with a space.</p>
<p>And if <code>param1</code> and <code>param2</code> are both numerical, we want to add both of them.</p>
<p>Shortly, we are adding some kind of <code>type guard</code> to prevent unexpected behavior.</p>
<blockquote>
<p>In future blogs, we'll explore in-depth concepts about <strong>type guards</strong> and other type guards beside <code>typeof</code>.</p>
</blockquote>
<h2 id="heading-literal-types">LITERAL TYPES:</h2>
<h3 id="heading-definition-6">DEFINITION:</h3>
<blockquote>
<p><strong>A literal type is a more concrete sub-type of a union type. The difference is that in union types, we specify the types of variables we are expecting, but in Literal types, we specify the exact value we are expecting.</strong></p>
</blockquote>
<p>Let's look at the example to understand this:</p>
<h3 id="heading-syntax-1">SYNTAX</h3>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> readOnly: <span class="hljs-string">"readonly"</span> = <span class="hljs-string">"readonly"</span>;
</code></pre>
<p>Specifically, we are declaring that you can only assign the <code>"readonly"</code> string to the <code>readOnly</code> variable. A string other than <code>"readonly"</code> cannot be assigned to this variable. If you do so, you will get a compilation error as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643395051458/GzXMHcQEY.png" alt="image.png" /></p>
<h3 id="heading-usecase-and-ide-support">USECASE AND IDE SUPPORT:</h3>
<p>If you want to accept only predefined values, you can assign a <code>literal type</code>. For example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> button: {
  label: <span class="hljs-built_in">string</span>;
  severity: <span class="hljs-string">"primary"</span> | <span class="hljs-string">"secondary"</span> | <span class="hljs-string">"danger"</span> | <span class="hljs-string">"warning"</span>;
  isSubmit: <span class="hljs-built_in">boolean</span>;
} = {
  label: <span class="hljs-string">"Submit"</span>,
  severity: <span class="hljs-string">"primary"</span>,
  isSubmit: <span class="hljs-literal">true</span>,
};
</code></pre>
<p>Using the example above, we are creating a <code>button</code> variable that has <code>label</code> - <code>string</code>, <code>isSubmit</code> - <code>boolean</code>, and <code>severity</code> - <code>"primary" | "secondary" | "danger" | "warning"</code>.</p>
<p>You will get the following compilation error if you try to assign a different string to the <code>severity</code> key, even if it is of type <code>string</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643635468436/IVFmEomyH.png" alt="image.png" /></p>
<p>A benefit of the Literal type is that you get autosuggestions for that particular key with all the possible values.</p>
<p>Take a look at the following image:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643635253462/K03WYmRsi.png" alt="image.png" /></p>
<p>This is useful in large applications when you don't know which value a given variable can have.</p>
<h2 id="heading-type-aliases">TYPE ALIASES:</h2>
<h3 id="heading-what-is-it">WHAT IS IT?:</h3>
<p>We might need to use longer types when working with <code>union types</code> or <code>literal types</code>. If we want to add another component apart from the <code>button</code>, let's say an <code>alertBar</code> that is also having the severity of <code>"primary" | "secondary" | "danger" | "warning"</code>, it's a bit cumbersome to write it again and again. We can avoid this by using <code>type aliases</code>.</p>
<h3 id="heading-why-and-how-to-use-it">WHY AND HOW TO USE IT?:</h3>
<p>Creating dynamic and reusable code is crucial. Don't-Repeat-Yourself (DRY) is an important principle to follow when writing TypeScript code. You can accomplish this using TypeScript aliases.</p>
<p>A custom type can be created by using the <code>type</code> keyword followed by the type's name. Let's look at the example below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> SeverityType = <span class="hljs-string">"primary"</span> | <span class="hljs-string">"secondary"</span> | <span class="hljs-string">"danger"</span> | <span class="hljs-string">"warning"</span>;

<span class="hljs-keyword">let</span> button: {
  label: <span class="hljs-built_in">string</span>;
  severity: SeverityType;
  isSubmit: <span class="hljs-built_in">boolean</span>;
} = {
  label: <span class="hljs-string">"Submit"</span>,
  severity: <span class="hljs-string">"primary"</span>,
  isSubmit: <span class="hljs-literal">true</span>,
};

<span class="hljs-keyword">let</span> alertBar: {
  message: <span class="hljs-built_in">string</span>;
  severity: SeverityType;
  duration: <span class="hljs-built_in">number</span>;
} = {
  message: <span class="hljs-string">"This is an error message"</span>,
  severity: <span class="hljs-string">"danger"</span>,
  duration: <span class="hljs-number">2000</span>,
};
</code></pre>
<p>By creating a <code>type</code>, you can now use <code>SeverityType</code> anywhere in your code as if it were a <code>number</code>, <code>string</code>, <code>boolean</code>, or any of the primitive or reference types. It's a valid type for TypeScript.</p>
<h3 id="heading-type-of-an-object">TYPE OF AN OBJECT:</h3>
<p><code>type</code> can also represent the structure of an object, such as what fields it should contain.</p>
<p>Creating a custom type for an object is as easy as using the <code>type</code> keyword followed by the type's name and specifying the fields of the type, as well as their types, in the <code>{}</code>.</p>
<p>In the above example, we can create the following custom types for <code>button</code> and <code>alertBar</code>:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> SeverityType = <span class="hljs-string">"primary"</span> | <span class="hljs-string">"secondary"</span> | <span class="hljs-string">"danger"</span> | <span class="hljs-string">"warning"</span>;

<span class="hljs-keyword">type</span> Button = {
  label: <span class="hljs-built_in">string</span>;
  severity: SeverityType;
  isSubmit: <span class="hljs-built_in">boolean</span>;
};

<span class="hljs-keyword">type</span> AlertBar = {
  message: <span class="hljs-built_in">string</span>;
  severity: SeverityType;
  duration: <span class="hljs-built_in">number</span>;
};

<span class="hljs-keyword">let</span> button: Button = {
  label: <span class="hljs-string">"Submit"</span>,
  severity: <span class="hljs-string">"primary"</span>,
  isSubmit: <span class="hljs-literal">true</span>,
};

<span class="hljs-keyword">let</span> alertBar: AlertBar = {
  message: <span class="hljs-string">"This is an error message"</span>,
  severity: <span class="hljs-string">"danger"</span>,
  duration: <span class="hljs-number">2000</span>,
};
</code></pre>
<p>We've created two new types in the above code: <code>Button</code> and <code>AlertBar</code>, which are type aliases for <code>button</code> and <code>alertBar</code>, respectively. Now, we can use those types anywhere in our code without having to rewrite them each time.</p>
<blockquote>
<p>We will use <code>interfaces</code> instead of types to describe an object's structure in future blogs.</p>
</blockquote>
<h2 id="heading-conclusion">CONCLUSION:</h2>
<ul>
<li><p>In this blog, we've covered some of the most common types of values you’ll find in TypeScript code.</p>
</li>
<li><p>Types can also be found in many places other than just type annotations. We reviewed the most basic and common types you might encounter when writing TypeScript code. These are the core building blocks of more complex types, which will be discussed in future blogs.</p>
</li>
</ul>
<p>Make sure to subscribe to our newsletter on <a target="_blank" href="https://blog.wajeshubham.in/">https://blog.wajeshubham.in/</a> and never miss any upcoming articles related to TypeScript and programming just like this one.</p>
<p>I hope this post will help you in your journey. Keep learning!</p>
<p>My <a target="_blank" href="https://wajeshubham.in">Website</a>, connect with me on <a target="_blank" href="https://www.linkedin.com/in/shubham-waje/">LinkedIn</a> and <a target="_blank" href="https://github.com/wajeshubham">GitHub</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Functions in TypeScript]]></title><description><![CDATA[WHAT ARE FUNCTIONS?

Functions are the fundamental building blocks of any application in JavaScript. They’re how you build up layers of abstraction, mimicking classes, information hiding, and modules.
In TypeScript, while there are classes, namespace...]]></description><link>https://blog.wajeshubham.in/functions-in-typescript</link><guid isPermaLink="true">https://blog.wajeshubham.in/functions-in-typescript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[functions]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Shubham Waje]]></dc:creator><pubDate>Thu, 12 Jan 2023 10:05:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1673517812716/f2a57f81-8bd5-4f32-8cd4-406c71cf3d81.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643662982228/65gUzA2VT.webp" alt="ddb2af52.webp" /></p>
<h2 id="heading-what-are-functions">WHAT ARE FUNCTIONS?</h2>
<blockquote>
<p><strong>Functions are the fundamental building blocks of any application in JavaScript. They’re how you build up layers of abstraction, mimicking classes, information hiding, and modules.</strong></p>
<p><strong>In TypeScript, while there are classes, namespaces, and modules, functions still play a key role in describing how to do things.</strong></p>
</blockquote>
<h2 id="heading-what-typescript-adds">WHAT TYPESCRIPT ADDS?</h2>
<blockquote>
<p><strong>Functions are the primary means of passing data around in JavaScript. TypeScript allows you to specify the types of both the input and output values of functions.</strong></p>
<p><strong>TypeScript also adds some new capabilities to the standard JavaScript functions to make them easier to work with.</strong></p>
</blockquote>
<h2 id="heading-syntax-and-structure">SYNTAX AND STRUCTURE:</h2>
<p>In TypeScript, function definition consists of a function name, its parameters with types, and its return type (which can be inferred by TypeScript).</p>
<h3 id="heading-declare-an-arrow-function">DECLARE AN ARROW FUNCTION:</h3>
<p>Following is the syntax to declare a function in TypeScript:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> functionName = (param1: <span class="hljs-built_in">string</span>): <span class="hljs-function"><span class="hljs-params">string</span> =&gt;</span> {
  <span class="hljs-comment">// ...</span>
  <span class="hljs-keyword">return</span> param1;
};

<span class="hljs-comment">// functionName = Name of the function</span>
<span class="hljs-comment">// param1 = Name of the parameter (optional)</span>
<span class="hljs-comment">// (...): string = Return type of the function</span>
</code></pre>
<p>In the above code, the syntax <code>(param1: string): string =&gt;</code> means a function with one parameter, named <code>param1</code>, of type <code>string</code>, that has a return value of type <code>string</code>.</p>
<p>If you don't specify the return type, TypeScript automatically infers the return type for you as shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643737505137/VsiPbTT-9.png" alt="image.png" /></p>
<p>Here, <code>const functionName: (param1: string) =&gt; string</code> means, a function with a name <code>functionName</code> with one parameter named <code>param1</code> of type <code>string</code> that has a return value of type <code>string</code>.</p>
<h3 id="heading-declare-a-function-with-function-keyword">DECLARE A FUNCTION WITH <code>function</code> KEYWORD:</h3>
<p>Declaring a function with the <code>function</code> keyword is almost similar to an arrow function.</p>
<p>Take a look at the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">functionName</span>(<span class="hljs-params">param1: <span class="hljs-built_in">string</span></span>): <span class="hljs-title">string</span> </span>{
  <span class="hljs-comment">// ...</span>
  <span class="hljs-keyword">return</span> param1;
}
<span class="hljs-comment">// functionName = Name of the function</span>
<span class="hljs-comment">// param1 = Name of the parameter (optional)</span>
<span class="hljs-comment">// (...): string = Return type of the function</span>
</code></pre>
<h2 id="heading-type-annotations">TYPE ANNOTATIONS:</h2>
<blockquote>
<p>When you declare a function, you can add type annotations after each parameter to declare what type of parameters the function accepts. You can add return type annotations to the function as well.</p>
<p><strong>Parameter type annotations go after the parameter name. Return type annotations appear after the parameter list.</strong></p>
</blockquote>
<h3 id="heading-parameter-type-annotations">PARAMETER TYPE ANNOTATIONS:</h3>
<p>Take a look at the following code:</p>
<pre><code class="lang-typescript">
<span class="hljs-keyword">const</span> add = <span class="hljs-function">(<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span></span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> a + b;
};

<span class="hljs-built_in">console</span>.log(add(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>));
</code></pre>
<p>In the above code, we declare an <code>add</code> function that accepts parameters <code>a</code> and <code>b</code> that is of type <code>number</code>.</p>
<p>So, if you try to break the rule and pass <code>string</code> instead of the <code>number</code>, you will get a compilation error as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643738509836/S_wMSUCm_.png" alt="image.png" /></p>
<p>Also, if you try to add parameters more than what a function is accepting, you will get a compilation error, unlike JavaScript.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643738670780/KewHF5Mxo.png" alt="image.png" /></p>
<h3 id="heading-return-type-annotations">RETURN TYPE ANNOTATIONS:</h3>
<p>Although we usually don’t need a return type annotation because TypeScript will infer the function’s return type based on its return statement. In some cases, you have to explicitly specify a return type for documentation purposes to prevent accidental changes or just for personal preference.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> returnANumber = (): <span class="hljs-function"><span class="hljs-params">number</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
};
</code></pre>
<p>Here, we are specifying that the <code>returnANumber</code> will return a value with a <code>type</code> <code>number</code>.</p>
<p>Now, if you specify the return type but don't return a value with valid <code>type</code>, TypeScript will throw a compilation error as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643740462239/B0VJ99DJg.png" alt="image.png" /></p>
<h4 id="heading-ide-support-for-return-type">IDE SUPPORT FOR RETURN TYPE:</h4>
<p>The advantage of knowing the return type of a function is you get great IDE support if you want to do more operations on the value that is being returned.</p>
<p>For example,</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> parseRange = (
  range: <span class="hljs-built_in">string</span>
): {
  start: <span class="hljs-built_in">number</span>;
  end: <span class="hljs-built_in">number</span>;
} =&gt; {
  <span class="hljs-keyword">let</span> [start, end] = range.split(<span class="hljs-string">"-"</span>);
  <span class="hljs-keyword">return</span> {
    start: <span class="hljs-built_in">parseInt</span>(start),
    end: <span class="hljs-built_in">parseInt</span>(end),
  };
};

<span class="hljs-keyword">let</span> parsedData = parseRange(<span class="hljs-string">"1-5"</span>);
</code></pre>
<p>In the above example, we have explicitly mentioned the return type of the <code>parseRange</code> function. However, even if we don't specify the return type, TypeScript will infer the return type for us.</p>
<p>If we try to access the start or end keys on the <code>parsedDate</code> variable, we will get autosuggestion from an IDE because TypeScript knows the return type of the <code>parseRange</code> function.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643741675666/eDJmAu1wP.png" alt="image.png" /></p>
<h4 id="heading-void-return-type"><code>void</code> RETURN TYPE:</h4>
<p>Similar to languages like Java, <code>void</code> is used when there is no data. For example, if a function does not return any value then you can specify <code>void</code> as a return type or let TypeScript infer the return type as <code>void</code>.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> helloWorld = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello World"</span>);
};

<span class="hljs-keyword">let</span> sayHello = helloWorld();

<span class="hljs-built_in">console</span>.log(sayHello); <span class="hljs-comment">// this will print undefined</span>
</code></pre>
<p>You will get a compilation error if you attempt to return any value other than <code>void</code> after specifying <code>void</code> as a return type for that function:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643783585562/HOhDbg4Cj.png" alt="image.png" /></p>
<p>You can only return <code>undefined</code> if you specify <code>void</code> as the return type. The following image shows valid and invalid return statements for a function with the return type of <code>void</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643783781425/wtEnghxj7.png" alt="image.png" /></p>
<blockquote>
<p><strong>Remember the Rule: "</strong><code>void</code> is the return type of a function/method that doesn’t explicitly return anything".</p>
<p><strong>When no return statement is provided and no explicit return type is specified in the function or method, it infers a</strong> <code>void</code> return type automatically.</p>
</blockquote>
<h2 id="heading-function-as-a-type">FUNCTION AS A TYPE:</h2>
<p>It is possible to assign a type to a variable that we want to use as a function with a specific parameter and return type. Here's how to declare one:</p>
<pre><code class="lang-typescript">
<span class="hljs-keyword">let</span> add: <span class="hljs-function">(<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span></span>) =&gt;</span> <span class="hljs-built_in">number</span>;

add = <span class="hljs-function">(<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span></span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> a + b;
};
</code></pre>
<p>In the above code, we are declaring a variable <code>add</code> and have assigned a type <code>(a: number, b: number) =&gt; number</code> <strong><em>(This is not an arrow function or a function declaration. Here, the left side of the</em></strong> <code>=&gt;</code> are the parameters that the function expects and the right side of the <code>=&gt;</code> is the return type of that function)</p>
<p>Using the <code>add</code> the variable we declared earlier, we can assign a function to it as a <code>value</code>.</p>
<p>TypeScript will throw an error stating that this variable only allows two parameters if we try to add another.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643802633672/xNQ48EMPE2.png" alt="image.png" /></p>
<h3 id="heading-pass-function-as-a-parameter">PASS <code>Function</code> AS A PARAMETER:</h3>
<p>Take a look at the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> sendMessage = (cb: <span class="hljs-function">(<span class="hljs-params">a: <span class="hljs-built_in">string</span></span>) =&gt;</span> <span class="hljs-built_in">void</span>) =&gt; {
  cb(<span class="hljs-string">"Hello, World"</span>);
};

sendMessage(<span class="hljs-function">(<span class="hljs-params">str</span>)=&gt;</span>{
  <span class="hljs-built_in">console</span>.log(str);
});
</code></pre>
<p>Here, the <code>sendMessage</code> function has a parameter named <code>cb</code> (callback function) with one parameter named <code>a</code>, of type <code>string</code>, that has no return value, since the function has been declared to have a return type of <code>void</code>.</p>
<p>Even if you return anything inside a callback, TypeScript <strong>won't</strong> throw a compilation error, instead, it will ignore it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643804386185/xmyJJbryx.png" alt="image.png" /></p>
<h3 id="heading-declare-function-type-inside-an-object">DECLARE <code>Function</code> TYPE INSIDE AN <code>object</code>:</h3>
<p>Earlier, we discussed the concept of an <code>object</code> type, which can hold a collection of different types. You can assign a <code>function</code> type to any of its keys.</p>
<h4 id="heading-general-syntax">GENERAL SYNTAX:</h4>
<p>Take a look at the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> person: {
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
  sayHi(): <span class="hljs-built_in">void</span>;
} = {
  name: <span class="hljs-string">"Max"</span>,
  age: <span class="hljs-number">30</span>,
  sayHi: <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hi"</span>);
  },
};
</code></pre>
<p>In the above code, we have a <code>person</code> object with a key named <code>say</code>, and it is a <code>function</code> that returns nothing.</p>
<p>The following is a <code>general</code> way of defining a function type. The other way to declare a function in an object is with the <code>property syntax</code>.</p>
<h4 id="heading-property-syntax">PROPERTY SYNTAX:</h4>
<p>The <code>sayHi</code> key in the above example can be declared in <code>property syntax</code>, which is more commonly used and readable.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> person: {
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
  sayHi: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;
} = {
  name: <span class="hljs-string">"Max"</span>,
  age: <span class="hljs-number">30</span>,
  sayHi: <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hi"</span>);
  },
};
</code></pre>
<p>The logic remains the same but this is a more readable and preferred format of assigning a function type.</p>
<h2 id="heading-unknown-type"><code>unknown</code> TYPE:</h2>
<p><code>unknown</code> is not commonly used but it can be helpful to be aware of it.</p>
<h3 id="heading-why-use-unknown-instead-of-any">WHY USE <code>unknown</code> INSTEAD OF <code>any</code>:</h3>
<p><code>unknown</code> and <code>any</code> are similar to some extent but <code>unknown</code> is a bit more restrictive than <code>any</code>. To understand this take a look at the following code:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">let</span> userInput: unknown;
<span class="hljs-keyword">let</span> userName: <span class="hljs-built_in">string</span>;

userInput = <span class="hljs-number">5</span>;
userInput = <span class="hljs-string">"John"</span>;
</code></pre>
<p>In the above code, we are having <code>userInput</code> which is having types as <code>unknown</code> and <code>userName</code> with type <code>string</code></p>
<p>Now, you can assign any value to the variable with the type <code>unknown</code>. So you won't get any compilation errors for assigning <code>5</code> and <code>"John"</code> to variable <code>userInput</code>.</p>
<p>But what happens if you try to assign <code>userInput</code> to <code>userName</code>?</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> userInput: unknown;
<span class="hljs-keyword">let</span> userName: <span class="hljs-built_in">string</span>;

userInput = <span class="hljs-number">5</span>;
userInput = <span class="hljs-string">"Max"</span>;

userName = userInput; <span class="hljs-comment">// This line will throw an error</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643805312622/vmPa8Hy24.png" alt="image.png" /></p>
<p>It says <code>Type 'unknown' is not assignable to type 'string</code> even though <code>string</code> has already been assigned one line before.</p>
<p>Since the <code>unknown</code> type can only be assigned to <code>any</code> type and the <code>unknown</code> type itself, it can never be assigned to another type.</p>
<h3 id="heading-use-type-guards-to-avoid-errors">USE TYPE GUARDS TO AVOID ERRORS:</h3>
<p>Adding type guards to the above code will allow it to work, as we saw in previous blogs.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> userInput: unknown;
<span class="hljs-keyword">let</span> userName: <span class="hljs-built_in">string</span>;

userInput = <span class="hljs-number">5</span>;
userInput = <span class="hljs-string">"Max"</span>;

<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> userInput === <span class="hljs-string">"string"</span>) {
  userName = userInput;
}
</code></pre>
<p>In the above code, we are only assigning <code>userInput</code> to <code>userName</code> only if userInput has a <code>string</code> type value.</p>
<h3 id="heading-difference-between-unknown-and-any">DIFFERENCE BETWEEN <code>unknown</code> AND <code>any</code>:</h3>
<p>What happens when you change the type of <code>userInput</code> from <code>unknown</code> to <code>any</code>?</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> userInput: <span class="hljs-built_in">any</span>;
<span class="hljs-keyword">let</span> userName: <span class="hljs-built_in">string</span>;

userInput = <span class="hljs-number">5</span>;
userInput = <span class="hljs-string">"Max"</span>;

userName = userInput; <span class="hljs-comment">// compile without an error</span>
</code></pre>
<p>The main difference between <code>unknown</code> and <code>any</code> is that <code>unknown</code> is much less permissive. We must perform some form of checking before performing most operations on values of type <code>unknown</code>, but we do not have to perform any checks before performing operations on values of type <code>any</code>.</p>
<h2 id="heading-never-type"><code>never</code> TYPE:</h2>
<p>As the type name suggests, <code>never</code> refers to a function that will never return a value, not even an <code>undefined</code> or a <code>null</code> value.</p>
<h3 id="heading-difference-between-never-and-void">DIFFERENCE BETWEEN <code>never</code> AND <code>void</code>:</h3>
<ul>
<li><p>The main difference between <code>never</code> and <code>void</code> is that <code>void</code> simply returns undefined if you try to access the return value from a function with <code>void</code> return type.</p>
</li>
<li><p>However, the function that returns <code>never</code> will cause the <strong>code to crash</strong>, and the code would not be executed further.</p>
</li>
</ul>
<h3 id="heading-example-1-function-that-throws-an-error">EXAMPLE 1 - FUNCTION THAT THROWS AN ERROR:</h3>
<p>Generally, when we throw an error from any function, its return type is inferred to be <code>never</code>. Let's take a look at the following function:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> generateError = (message: <span class="hljs-built_in">string</span>, code: <span class="hljs-built_in">number</span>): <span class="hljs-function"><span class="hljs-params">never</span> =&gt;</span> {
  <span class="hljs-keyword">throw</span> {
    message,
    code,
  };
};

<span class="hljs-keyword">const</span> returnedValue = generateError(<span class="hljs-string">"Something went wrong!"</span>, <span class="hljs-number">500</span>);
<span class="hljs-built_in">console</span>.log(returnedValue);
</code></pre>
<p>We are throwing an error whenever we call the above function. This is what we see in the console:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644043010469/lLA5PQ6e5.png" alt="image.png" /></p>
<p>We got the error we threw, but we didn't get any output from <code>console.log(returnedValue)</code>, not even <code>undefined</code>. It indicates that a function with a return type never caused the script to crash.</p>
<h3 id="heading-example-2-infinite-loop">EXAMPLE 2 - INFINITE LOOP:</h3>
<p>Another type of function that returns <code>never</code> is the one with an infinite while loop.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> infiniteLoop = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {}
};

<span class="hljs-keyword">const</span> returnedValue = infiniteLoop();
<span class="hljs-built_in">console</span>.log(returnedValue);
</code></pre>
<p>In the above function, the <code>infiniteLoop</code> the function runs continuously, which breaks the script. If you hover over the <code>infiniteLoop</code> function, you'll see that TypeScript has inferred the return type as <code>never</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644043297344/iCt190EwN.png" alt="image.png" /></p>
<h2 id="heading-conclusion">CONCLUSION:</h2>
<ul>
<li><p>In TypeScript, functions are the building blocks of applications. In this article, we learned how to build type-safe functions using TypeScript, different types of annotations, how to use functions as types, and the concept of <code>unknown</code> and <code>never</code> types.</p>
</li>
<li><p>Having this knowledge will allow for more type-safe and easy-to-maintain functions throughout your code.</p>
</li>
</ul>
<p>Make sure to subscribe to our newsletter on <a target="_blank" href="https://blog.wajeshubham.in"><strong><em>https://blog.wajeshubham.in</em></strong></a> and never miss any upcoming articles related to TypeScript and programming just like this one.</p>
<p>I hope this post will help you in your journey. Keep learning!</p>
<p>My <a target="_blank" href="https://wajeshubham.in"><strong><em>Website</em></strong></a>, connect with me on <a target="_blank" href="https://www.linkedin.com/in/shubham-waje/"><strong><em>LinkedIn</em></strong></a> and <a target="_blank" href="https://github.com/wajeshubham"><strong><em>GitHub</em></strong></a>.</p>
]]></content:encoded></item><item><title><![CDATA[Introduction to TypeScript]]></title><description><![CDATA[In this article, you will learn what TypeScript is all about: its installation, the differences between TypeScript and JavaScript, its basic types and concepts, and how to configure TypeScript by adding the tsconfig.json file.

WHAT IS TYPESCRIPT?

T...]]></description><link>https://blog.wajeshubham.in/introduction-to-typescript</link><guid isPermaLink="true">https://blog.wajeshubham.in/introduction-to-typescript</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[React]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Shubham Waje]]></dc:creator><pubDate>Thu, 12 Jan 2023 09:39:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1673516184719/42ba3fbe-c592-4c63-ba76-5f874d5e57a4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, you will learn what TypeScript is all about: its installation, the differences between TypeScript and JavaScript, its basic types and concepts, and how to configure TypeScript by adding the <code>tsconfig.json</code> file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643018108207/nQV-PBizd.png" alt="cover.png" /></p>
<h2 id="heading-what-is-typescript">WHAT IS TYPESCRIPT?</h2>
<blockquote>
<p><strong>TypeScript</strong> is an open-source Object Oriented Programming language developed and maintained by Microsoft.</p>
<p><strong>TypeScript</strong> is a strongly typed language. It is a superset of JavaScript, which means anything that is implemented in JavaScript can be implemented using <strong>TypeScript</strong> along with the enhanced features provided by <strong>TypeScript</strong>.</p>
<p>As <strong>TypeScript</strong> code is converted to JavaScript code which makes it easier to integrate into JavaScript projects. It is designed mainly for large-scale projects.</p>
<p><strong>TypeScript</strong> is a primary language for <strong>the Angular</strong> framework. Angular is an open-source web application framework maintained by the Angular Team at Google.</p>
</blockquote>
<p><strong><em>Why do we use TypeScript?</em></strong></p>
<p><strong>1. Static type checking:</strong> Like other high-level programming languages like JAVA, TypeScript does provide static type checking which requires some extra code but it has its advantages.</p>
<p><strong>2. Classes and Interfaces:</strong> TypeScript supports Classes that provide the ability to use object-oriented programming in our applications. It also provides encapsulation, inheritance, and access modifiers that JavaScript can't offer (In 2015 with ECMA script 6 classes have been introduced but we can't use access modifiers in them unlike TypeScript).</p>
<p><strong>3. Better developer experience:</strong> TypeScript code is documentation in itself. Because modern IDEs support TypeScript autosuggestions which is a great tool to develop apps at a faster pace and with fewer bugs.</p>
<p><strong>4. Runs everywhere:</strong> TypeScript is technically just JavaScript with enhanced tools. Thus, if you are writing code using TypeScript, it will be converted to JavaScript. It can be used for both front-end development (React, Angular) and back-end development (Node.js).</p>
<h2 id="heading-difference-between-typescript-and-javascript">DIFFERENCE BETWEEN TYPESCRIPT AND JAVASCRIPT</h2>
<ul>
<li><p>TypeScript is known as an Object-oriented programming language whereas JavaScript is a scripting language.</p>
</li>
<li><p>TypeScript has a feature known as Static typing but JavaScript does not have this feature.</p>
</li>
<li><p>TypeScript has an Interface but JavaScript does not have an Interface.</p>
</li>
<li><p>TypeScript provides compile-time safety (You will get possible errors while writing code) but JavaScript does not provide compile-time safety (JavaScript throws runtime errors which we can prevent using TypeScript).</p>
</li>
</ul>
<h2 id="heading-required-tools">REQUIRED TOOLS:</h2>
<p><strong>Here is a list of recommended tools that will assist you in getting the most out of TypeScript:</strong></p>
<p><strong>1. VS Code</strong> (Install VS Code from <a target="_blank" href="https://code.visualstudio.com/">https://code.visualstudio.com/</a>) <em>(Since Microsoft maintains TypeScript and VS Code, I believe there is no IDE that provides better support for TypeScript than VS Code.)</em></p>
<p><strong>2. Node.JS</strong> (Install node from <a target="_blank" href="https://nodejs.org">https://nodejs.org</a>)</p>
<p><strong>3. NPM</strong></p>
<h2 id="heading-installation">INSTALLATION:</h2>
<p>Run the following command in your terminal (make sure to run it as an administrator) to install <strong>TypeScript</strong> globally</p>
<pre><code class="lang-bash">npm install -g typescript
</code></pre>
<p>Once done run the following command to check if TypeScript is installed on your machine</p>
<pre><code class="lang-bash">npx tsc
</code></pre>
<p>As long as you are getting the version number and some common commands you are good to go!</p>
<h2 id="heading-lets-set-up-a-project">LET'S SET UP A PROJECT:</h2>
<p>Open a folder in VS code and create <code>index.html</code> and <code>index.ts</code> files in it.</p>
<p>Now run the following command to initialize a project.</p>
<pre><code class="lang-bash">npm init
<span class="hljs-comment"># it will ask some questions just hit enter with default options</span>
</code></pre>
<p>It will create a <code>package.json</code> file in your root folder</p>
<h3 id="heading-extension-for-vs-code-users">EXTENSION FOR <code>VS CODE</code> USERS:</h3>
<p>If you're using <code>VS Code</code>, you can use an extension called <code>live server</code> (published by Ritwick Dey) to have the browser automatically refresh when you save your changes.</p>
<p>Select <strong>Extensions</strong> &gt; <strong>Search for "live server"</strong> and then install the first extension written by Ritwick Dey.</p>
<h3 id="heading-package-for-non-vs-code-users">PACKAGE FOR NON <code>VS CODE</code> USERS</h3>
<p>Run the following command to install a required package:</p>
<pre><code class="lang-bash">npm install --save-dev lite-server
</code></pre>
<p>This will install <code>live-server</code> as a dev dependency (we only need this for development)</p>
<p>Add a start script to start the project. In <code>package.json</code> inside <code>scripts</code> add the following line:</p>
<pre><code class="lang-json">...
 <span class="hljs-string">"description"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-string">"main"</span>: <span class="hljs-string">"index.js"</span>,
  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>,
    <span class="hljs-attr">"start"</span>: <span class="hljs-string">"lite-server"</span>
  },
...
</code></pre>
<p>If you do not use the <code>live server</code> extension, you have to start the <code>lite-server</code> using the following command:</p>
<pre><code class="lang-bash">npm start
</code></pre>
<h3 id="heading-first-typescript-code">FIRST TYPESCRIPT CODE:</h3>
<p>Add the following code to your <code>index.html</code> file:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Typescript intro<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"root"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Hello...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> 
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Add the following code to the <code>index.ts</code> file to check if our setup is working:</p>
<pre><code class="lang-ts"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello world!"</span>)
</code></pre>
<p>To run the live server go to <code>index.html</code> &gt; right-click and select <code>Open with the live server</code> option. It will start a local server that will serve our index.html file.</p>
<p>For <code>lite-server</code> users run <code>npm start</code> and you are good to go.</p>
<p>Please run the following command to compile our <code>index.ts</code> into <code>index.js</code> since, as I mentioned earlier, our browser only knows JavaScript, so we must compile our TypeScript code into JavaScript.</p>
<pre><code class="lang-bash">tsc index.ts -w
</code></pre>
<p><code>tsc</code> is a high-level compiler that outputs a JavaScript file, <code>.js</code>, from a TypeScript file, <code>.ts</code>. As a result of the above command, an <code>index.js</code> file is created in the root directory, which is linked in the index.html file using the <code>script</code> tag.</p>
<p><code>-w</code> flag in the above command indicates <code>watch mode</code>. The above command will automatically compile the <code>.ts</code> file whenever you make any changes and save the file.</p>
<p>Open the browser and you should see <code>Hello World</code> printed in your browser console.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643024842761/h_hI522bJ.png" alt="image.png" /></p>
<p>To confirm it's working, change the <code>index.ts</code> file, and write console.log(<code>Hello World...)</code> in it, and save the file.</p>
<p>Open the browser, and you should see <code>Hello World...</code> printed in your browser console without reloading.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643024705359/DyEO83x9t.png" alt="image.png" /></p>
<h2 id="heading-core-basic-types-in-typescript">CORE BASIC TYPES IN TYPESCRIPT:</h2>
<p>TypeScript has some basic and core types that JavaScript understands as well. These includes:</p>
<pre><code class="lang-typescript">- <span class="hljs-built_in">number</span> <span class="hljs-comment">// 1, 2, 3</span>
- <span class="hljs-built_in">string</span> <span class="hljs-comment">// "Hello", "World"</span>
- <span class="hljs-built_in">object</span> <span class="hljs-comment">// {name: "John", age: 30}</span>
- <span class="hljs-built_in">boolean</span> <span class="hljs-comment">// true, false</span>
</code></pre>
<blockquote>
<p>TypeScript also has a type called <code>Array</code>. However, it is a generic type and is a bit of an advanced topic that we will discuss more in-depth in future blogs.</p>
</blockquote>
<h2 id="heading-typescript-syntax-and-some-examples">TYPESCRIPT SYNTAX AND SOME EXAMPLES:</h2>
<p><code>number</code>, <code>string</code> and <code>boolean</code> TYPES IN TYPESCRIPT:</p>
<p><strong>Let's write some code to understand the above types.</strong></p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> a: <span class="hljs-built_in">number</span> = <span class="hljs-number">5</span>; 
<span class="hljs-keyword">const</span> b: <span class="hljs-built_in">string</span> = <span class="hljs-string">"hello world"</span>;
<span class="hljs-keyword">const</span> c: <span class="hljs-built_in">boolean</span> = <span class="hljs-literal">true</span>;
</code></pre>
<p>Here's how we declare a variable in TypeScript. Here, <code>a</code> is the name of the variable, <code>number</code> is the type of that variable, and <code>5</code> is its value.</p>
<h3 id="heading-type-inference">TYPE INFERENCE:</h3>
<blockquote>
<p>In the above example, you can omit the <code>: number</code>, <code>: string</code>, or <code>: boolean</code> part since TypeScript automatically infers the type of that variable based on the value you are assigning. That's called Type inference.**</p>
</blockquote>
<p><strong>Take a look at the following function, it adds two numbers and returns a sum:</strong></p>
<pre><code class="lang-typescript">
<span class="hljs-comment">// num1 is a type of number and :number before =&gt; mark is the return type of that number</span>
<span class="hljs-comment">// but typescript detects return type of function automatically most of the time</span>
<span class="hljs-keyword">const</span> add = (num1: <span class="hljs-built_in">number</span>, num2: <span class="hljs-built_in">number</span>):<span class="hljs-function"><span class="hljs-params">number</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> num1 + num2;
};

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"ANSWER: "</span>, add(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>));
</code></pre>
<p>Save the file. Ensure that your <code>tsc index.ts -w</code> command is running. You should now see <code>ANSWER: 3</code> in the console in your browser.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643026074947/p-NkB33L4.png" alt="image.png" /></p>
<p>Now in the above <code>add</code> function 1st argument <code>num1</code> is <code>inferred</code> to type <code>number</code> same for <code>num2</code>. We are adding two numbers, and everything is working fine.</p>
<p>Here, in the <code>add</code> function, the first argument <code>num1</code> is inferred to be of type <code>number</code>, and the same for <code>num2</code>. We are adding two numbers, and everything is working fine.</p>
<p>Let's see what happens if we pass a string in the <code>add</code> function.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643026215444/0SW4W2aEz.png" alt="image.png" /></p>
<p>We get a compilation error from TypeScript. You can see this in the above image. In JavaScript, you won't get that error. Instead, you will get strange behavior, and it will print <code>ANSWER: HELLO2</code> in the console. Because JavaScript converts <code>num2</code> to a <code>string</code> and concatenates it with <code>HELLO</code> which is unwanted behavior.</p>
<p>TypeScript throws a compilation error. This can be seen in the image above. JavaScript will not throw this error. In this case, you will see abnormal behavior and it will display <code>ANSWER: HELLO2</code> in the console because JavaScript converts <code>num2</code> to a <code>string</code> and concatenates that string with <code>HELLO</code>, which is unintended.</p>
<p>It could happen when you are getting value from user input from which you are expecting a <code>number</code> but it's returning a value in <code>string</code> format so if you pass <code>"2"</code> and <code>"3"</code> to the above <code>add</code> function in JavaScript it will return <code>23</code>.</p>
<p>You may encounter this issue when you receive input from the user and expect a <code>number</code> but it's returning a value in <code>string</code> format. For example, if you pass <code>"2"</code> and <code>"3"</code> to the above <code>add</code> function in JavaScript, it will return <code>23</code>.</p>
<p><strong>Let's write a function to understand more.</strong></p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> concatenateAndConvertToUppercase = <span class="hljs-function">(<span class="hljs-params">a: <span class="hljs-built_in">string</span>, b: <span class="hljs-built_in">string</span></span>) =&gt;</span> {
    <span class="hljs-keyword">let</span> uppercaseA = a.toUpperCase();
    <span class="hljs-keyword">let</span> uppercaseB = b.toUpperCase();
    <span class="hljs-keyword">return</span> uppercaseA + uppercaseB;
};

<span class="hljs-built_in">console</span>.log(concatenateAndConvertToUppercase(<span class="hljs-string">'hello'</span>, <span class="hljs-string">'world'</span>));
</code></pre>
<p>In addition, when you assign a type to a variable or argument, your IDE shows related methods for that type.</p>
<p>The example above shows that the variables <code>a</code> and <code>b</code> have been assigned the type <code>string</code>. The IDE picks it up and displays all the methods a <code>string</code> can have as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643029632932/L1zJdL9JJ.png" alt="image.png" /></p>
<blockquote>
<p><strong>This is why type assignments are important as they prevent runtime errors, and unpredictable behavior, and speed up the development process.</strong></p>
</blockquote>
<h2 id="heading-configure-typescript">CONFIGURE TYPESCRIPT:</h2>
<p>In a real-world project, when you are using TypeScript with something like React or Angular, you will have a <code>tsconfig.json</code> file that you can use to set up TypeScript compilation rules.</p>
<p><code>tsconfig.json</code> file is an indicator that the directory is the root of the TypeScript project.</p>
<p>Run the following command to initialize a <code>tsconfog.json</code> file:</p>
<pre><code class="lang-bash">tsc --init
</code></pre>
<p>It will create a <code>tsconfig.json</code> file in the root directory with some default options.</p>
<p>If you remember we were running <code>tsc index.ts -w</code> to compile our <code>index.ts</code> into <code>index.js</code>, which means we can only compile one file at a time, which is not feasible.</p>
<p>Therefore, once you have added <code>tsconfig.json</code> you can run the following command, which will compile all the <code>.ts</code> files into equivalent <code>.js</code> files.</p>
<pre><code class="lang-bash">tsc -w
</code></pre>
<p>To test this, add the <code>app.ts</code> file in the root folder and add the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">"This is app.ts file"</span>);
</code></pre>
<p>Now, run <code>tsc -w</code> it will generate two files <code>index.js</code> and <code>app.js</code>.</p>
<h3 id="heading-understanding-tsconfigjson">UNDERSTANDING <code>tsconfig.json</code>:</h3>
<p>What makes this new <code>tsconfig.json</code> stand out is how well-documented all the options are. All the options are quite self-explanatory. Despite this, you may not have to use all of these options for most projects.</p>
<p>Let's take a look at the most important and widely used options:</p>
<p><code>target</code>: This tells <code>TypeScript</code> the version of JavaScript it should compile into. By default, it is set to JS version ES2016, which means that TypeScript code will be compiled into JS version ES2016.</p>
<p><code>lib</code>: It provides libraries that we want to make available to TypeScript globally. It is commented by default and contains some default values. <code>DOM</code>, <code>ES2016</code>, <code>DOM.Iterable</code>, and <code>ScriptHost</code> are the default libraries. When you uncomment that and check out <code>index.ts</code>, it will throw an error <code>Cannot find the name 'console'</code> since the <code>DOM</code> is not included in the library.</p>
<p><code>jsx</code>: This is related to ReactJs. Controls how JSX constructs are emitted in JavaScript files.</p>
<p><code>experimentalDecorators</code>: This will allow the use of <code>decorators</code> in your TypeScript file. We will take a look into what <code>decorators</code> are and how to use them in future blogs.</p>
<p><code>sourceMap</code>: It helps us in debugging because it creates a <code>.</code><a target="_blank" href="http://js.map"><code>js.map</code></a> file. It is a bridge by which you can debug your TypeScript files in the browser's dev tools.</p>
<p><code>allowJs</code>: If you enable this the JavaScript files will also get compiled along with TypeScript files.</p>
<p><code>rootDir</code>: As the name suggests, it shows the path to your root folder or where your TypeScript files are located.</p>
<p><code>outDir</code>: It shows where you want to keep your compiled JavaScript files. Currently, after compilation, our <code>.ts</code> and <code>.js</code> files are getting stored in the root directory. Let's configure <code>outDir</code> to understand the concept.</p>
<p>Uncomment <code>outDir</code> from <code>tsconfig.json</code>:</p>
<pre><code class="lang-json">...
<span class="hljs-string">"outDir"</span>: <span class="hljs-string">"./dist"</span>, 
...
</code></pre>
<p>Now delete <code>index.js</code> and <code>app.js</code> files from the root directory and run the following command:</p>
<pre><code class="lang-bash">tsc -w
</code></pre>
<p>The <code>dist</code> folder will be created in the root directory. This folder will contain all of your <code>.js</code> files as you can see in the following image.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643052280631/a0IZMjRsT.png" alt="image.png" /></p>
<p>To get the output on the browser, we need to update <code>index.html</code> to match the new location of <code>.js</code> files. Change the <code>index.html</code> file as follows:</p>
<pre><code class="lang-html">...
 <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"root"</span>&gt;</span>Hello....<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./dist/index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
...
</code></pre>
<ul>
<li><p><code>removeComments</code>: This will remove all the comments from compiled <code>.js</code> files that you have added in <code>.ts</code> files</p>
</li>
<li><p><code>noEmit</code>: It will restrict the generation of compiled <code>.js</code> files.</p>
</li>
<li><p><code>noEmitOnError</code>: This will avoid generating compiled <code>.js</code> files if your <code>.ts</code> file has an error in it.</p>
</li>
<li><p><code>strict</code>: It enables all strict type-checking options. If you set this to <code>false</code> you will lose all the powers of TypeScript.</p>
</li>
<li><p><code>noImplicitAny</code>: This shows an error when we don't give a type to unassigned parameters. Let's see an example:</p>
</li>
</ul>
<p>Take a look at the following image:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643051123270/5uQ1ZyUKN.png" alt="image.png" /></p>
<p>There is no type assigned to the <code>data</code> parameter in the above code, which could result in unexpected behavior if the code is complex.</p>
<ul>
<li><code>strictNullChecks</code>: It tells TypeScript that shows a warning when any value which possibly is <code>null</code>. Let's take an example:</li>
</ul>
<p>In <code>index.html</code> add <code>button</code> tag with <code>id</code> <code>my-btn</code>:</p>
<pre><code class="lang-html">...
 <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"root"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my-btn"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./dist/index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
...
</code></pre>
<p>Now, let's access this button in the <code>index.ts</code> file:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">let</span> btn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'my-btn'</span>);

btn.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Clicked'</span>);
});
</code></pre>
<p>If you notice TypeScript will throw an error for <code>Object is possibly null</code>, which means the <code>btn</code> variable might be <code>null</code>, and you could receive a runtime error saying <code>Cannot read property addEventListener of "null"</code>.</p>
<p>We know as a developer that <code>button</code> with <code>id</code> <code>my-btn</code> exists. To make the above code work, you have to do the following:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> btn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"my-btn"</span>)! <span class="hljs-keyword">as</span> HTMLButtonElement;

btn.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Clicked"</span>);
});
</code></pre>
<p>In this case, we are telling TypeScript that you will get a <code>button</code> with the id <code>my-btn</code>. Consider this variable as an <code>HTMLButtonElement</code>. As we will discover in future blogs, this is called "type casting".</p>
<ul>
<li><p><code>noUnusedLocals</code>: This option will show a warning if any unused variables are declared but never used.</p>
</li>
<li><p><code>noUnusedParameters</code>: This option will show a warning if any unused function parameters are declared but never used.</p>
</li>
<li><p><code>noImplicitReturns</code>: TypeScript will throw an error if your function has a conditional return. Take a look at the following code:</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643052670131/MVIJQLENS.png" alt="image.png" /></p>
<p>If you are returning anything, you must return a value after the conditional return statement. Therefore, you need to add a <code>return</code> outside the if block as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643052749679/qROJJkkl2.png" alt="image.png" /></p>
<p>Other options are a bit on the advanced side and need more knowledge about TypeScript. We will cover those in future blogs.</p>
<h2 id="heading-conclusion">CONCLUSION:</h2>
<ul>
<li><p>TypeScript brings a lot of benefits to our productivity and developer experience. It is not unique to Angular, other powerful frontend frameworks such as React and Vue are starting to be used with TypeScript to allow developer teams to create applications that are reliable, sustainable, and scalable.</p>
</li>
<li><p>JavaScript and TypeScript are continually evolving but not competing against each other. Typescript was created to complement and enhance JavaScript - not to replace it. The future may see them becoming very similar in features but with TypeScript remaining the statically-typed alternative.</p>
</li>
<li><p>With this TypeScript introduction, we’ve just scratched the surface of all the amazing things that we can do with TypeScript.</p>
</li>
</ul>
<p>Also, Make sure to subscribe to our newsletter on <a target="_blank" href="https://blog.wajeshubham.in/">https://blog.wajeshubham.in</a> and never miss any upcoming articles related to TypeScript and programming just like this one.</p>
<p>I hope this post will help you in your journey. Keep learning!</p>
<p>My <a target="_blank" href="https://wajeshubham.in"><strong><em>Website</em></strong></a>, connect with me on <a target="_blank" href="https://www.linkedin.com/in/shubham-waje/"><strong><em>LinkedIn</em></strong></a> and <a target="_blank" href="https://github.com/wajeshubham"><strong><em>GitHub</em></strong></a>.</p>
]]></content:encoded></item></channel></rss>