<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: ShUbHaM13M</title>
    <description>The latest articles on Forem by ShUbHaM13M (@shubham13m).</description>
    <link>https://forem.com/shubham13m</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F570205%2F49bfa8a4-692e-4e61-b74f-a08344f38065.png</url>
      <title>Forem: ShUbHaM13M</title>
      <link>https://forem.com/shubham13m</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/shubham13m"/>
    <language>en</language>
    <item>
      <title>Opensource Contribution</title>
      <dc:creator>ShUbHaM13M</dc:creator>
      <pubDate>Tue, 14 Nov 2023 14:11:52 +0000</pubDate>
      <link>https://forem.com/shubham13m/opensource-contribution-2nna</link>
      <guid>https://forem.com/shubham13m/opensource-contribution-2nna</guid>
      <description>&lt;p&gt;This is a guide to get started with Opensource contribution on Git. In order to contribute to a repository on Git we first have to create a fork of the repository in our personal Git space.&lt;/p&gt;

&lt;p&gt;The project that I will work on is a Chat application. I will work on adding the functionality to support rendering links and opening the URL in another tab, currently it just renders it as a text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IABvzxZX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vht17fd217dhn5szh74w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IABvzxZX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vht17fd217dhn5szh74w.png" alt="Fork git repo" width="786" height="253"&gt;&lt;/a&gt;Forking the repo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4D6UUHJI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dw8li0n1sab9lvcstssl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4D6UUHJI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dw8li0n1sab9lvcstssl.png" alt="Naming the repo" width="800" height="491"&gt;&lt;/a&gt;Naming the repo&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The name of the repo doesn't have to be the same as the original repo&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After creating a fork we can clone the repo. I am cloning the repo using SSH. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IdRSPgj3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kyzevuvj3xrz1h0zj04w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IdRSPgj3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kyzevuvj3xrz1h0zj04w.png" alt="Cloning the repo" width="677" height="663"&gt;&lt;/a&gt;Cloning the repo&lt;/p&gt;

&lt;p&gt;Next we have to add another remote to the cloned repo. This remote is the repo URL of the original author of the repo. Using this remote we can sync the cloned repo to the latest changes. I have used the HTTPs URL in this case as I only have read access to this repo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RjeEnaDr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bro5t9txna1w3l0y0q2z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RjeEnaDr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bro5t9txna1w3l0y0q2z.png" alt="Adding remote to the original repo" width="800" height="142"&gt;&lt;/a&gt;Adding remote to the original repo&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Usually I will just name it same as the author's name&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can check if adding the remote was successful using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next up we can just pull from the original repo, just to get the latest changes if any before continuing. It is a good idea to stay up to date with the original repo to prevent possibility of merge conflicts. &lt;/p&gt;

&lt;p&gt;In order to work on a new feature create a new branch and add the changes and updates in this branch, commit and then push the changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0KTW1H-f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iu6crtffgpr6x00tdigo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0KTW1H-f--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iu6crtffgpr6x00tdigo.png" alt="Creating a new branch" width="800" height="221"&gt;&lt;/a&gt;Creating a new branch&lt;/p&gt;

&lt;p&gt;These changes are only going to be pushed on the forked repo in our workspace as we don't have the write access to the original repo anyways.&lt;/p&gt;

&lt;p&gt;After working on the feature and pushing to the forked repo we can send a pull request to the original repo, adding a descriptive message to the changes made. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ljq1hf-M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uum0i6wkp64zr1eo7n52.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ljq1hf-M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uum0i6wkp64zr1eo7n52.png" alt="Creating a pull request" width="800" height="222"&gt;&lt;/a&gt;Creating a pull request to the original repo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--le4BQoNf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4z2g7zmyv5mrd0567hwi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--le4BQoNf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4z2g7zmyv5mrd0567hwi.png" alt="Leaving a descriptive change log for the author" width="800" height="554"&gt;&lt;/a&gt;Leaving a descriptive change log for the author&lt;/p&gt;

&lt;p&gt;The author can then review the changes, and merge the pull request.&lt;br&gt;
That's the basic of contributing to a repository on Github, Gitlab or any other VCs.&lt;br&gt;
Make sure to also go through the licensing of the repositories.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>git</category>
      <category>github</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Elevate Your Development Workflow with TypeScript</title>
      <dc:creator>ShUbHaM13M</dc:creator>
      <pubDate>Mon, 18 Sep 2023 08:30:08 +0000</pubDate>
      <link>https://forem.com/shubham13m/elevate-your-development-workflow-with-typescript-56oi</link>
      <guid>https://forem.com/shubham13m/elevate-your-development-workflow-with-typescript-56oi</guid>
      <description>&lt;p&gt;Recently I have been working on a short project trying out Next.js&lt;br&gt;
And I have setup the project with TypeScript.&lt;br&gt;
Here's a gist of what the project is -&lt;br&gt;
Users can create, share forms, and get responses on the form.&lt;/p&gt;

&lt;p&gt;I have a page for creating forms which is wrapped in a React Context that stores the state of the form.&lt;/p&gt;

&lt;p&gt;This is the interface of the state of a form.&lt;br&gt;
The form consists of a unique &lt;em&gt;id&lt;/em&gt;, &lt;em&gt;title&lt;/em&gt;, &lt;em&gt;description&lt;/em&gt; and an array of &lt;em&gt;questions&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CreateFormState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;questions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Question&lt;/strong&gt; is defined as a type consisting of fields - &lt;em&gt;id&lt;/em&gt;, &lt;em&gt;title&lt;/em&gt; and &lt;em&gt;answerType&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Question&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;answerType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AnswerType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The type of Question is a bit more complex than this as I also have to keep track of the state of answers&lt;br&gt;&lt;br&gt;
for example the options of the checkbox/radio the user inputs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;AnswerType&lt;/strong&gt; is type that defines what type of response the question can accept. Depending on the selected answerType a different input component is rendered.&lt;br&gt;&lt;br&gt;
A normal input for short-answer, a list of checkboxes for checkbox-answer, and so on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AnswerType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;short-answer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;long-answer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;radio-answer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checkbox-answer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frj2jv3x1zl1q3tmtz1y2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frj2jv3x1zl1q3tmtz1y2.png" alt="Question with short answer"&gt;&lt;/a&gt;&lt;/p&gt;
Question with short answer

  

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdud8x6xe951jmyfmwxjx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdud8x6xe951jmyfmwxjx.png" alt="Question with checkboxes"&gt;&lt;/a&gt;  &lt;/p&gt;
Question with check boxes






&lt;p&gt;The data is stored using the useReducer hook from React.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dispatchFormData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;formDataReducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;initialFormState&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the reducer function which specifies how the state gets updated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;formDataReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreateFormState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreateFormAction&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;CreateFormState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;CreateFormActionKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UPDATE_TITLE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;CreateFormActionKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UPDATE_DESCRIPTION&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;[Note]: Not all actions are present in this code snippet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is where the TypeScript's type-checking is really helpful. As I can define the type of actions the reducer function can accept and the type of payload that needs be sent when calling the function.&lt;/p&gt;

&lt;p&gt;Here are the type of actions that can be performed on the create form state. This is defined as a TypeScript &lt;strong&gt;Enum&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
These actions define updating the title and description of the form respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;CreateFormActionKind&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;UPDATE_TITLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UPDATE_TITLE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;UPDATE_DESCRIPTION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UPDATE_DESCRIPTION&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the action defining the type of the payload as &lt;em&gt;string&lt;/em&gt; when we are updating the title or the description of the question.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CreateFormAction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreateFormActionKind&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's add another action for adding a new question to the &lt;em&gt;questions&lt;/em&gt; array of the create form state. For that we need to add a new entry in the &lt;strong&gt;CreateFormActionKind&lt;/strong&gt; enum.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;CreateFormActionKind&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;UPDATE_TITLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UPDATE_TITLE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;UPDATE_DESCRIPTION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UPDATE_DESCRIPTION&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ADD_QUESTION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ADD_QUESTION&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now let's handle this action in the reducer function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;formDataReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreateFormState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreateFormAction&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;CreateFormState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;CreateFormActionKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ADD_QUESTION&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;questions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;questions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But adding this action in the function causes error. Since the type of &lt;em&gt;payload&lt;/em&gt; is defined as string in the &lt;strong&gt;CreateFormAction&lt;/strong&gt; and we are trying to push that to the questions array which is of type &lt;strong&gt;Question&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ef3hldnjnr9txq09mt2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ef3hldnjnr9txq09mt2.png" alt="TypeScript error because payload is defined as a string"&gt;&lt;/a&gt;  &lt;/p&gt;
TypeScript error because payload is defined as a string



&lt;p&gt;To fix this we will have to modify the &lt;em&gt;CreateFormAction&lt;/em&gt; a bit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CreateFormAction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;CreateFormActionKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UPDATE_TITLE&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;CreateFormActionKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UPDATE_DESCRIPTION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreateFormActionKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ADD_QUESTION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We defined CreateFormAction as Union of types so if -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ActionKind is UPDATE_TITLE or UPDATE_DESCRIPTION then the type of payload should be &lt;strong&gt;string&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;ActionKind is ADD_QUESTION then the type of payload should be &lt;strong&gt;Question&lt;/strong&gt; and we will have to pass a Question object to the function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And now we should be able to use this action for adding new questions. If we try to call this dispatch function in another component we will know the actions that can be performed on the state, the associated type of payload that the action accepts and we also get the Intellisense and auto-completion if we use an IDE with LSP.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl6uz6ljim3cca1rs1sc8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl6uz6ljim3cca1rs1sc8.png" alt="Trying to pass string as the payload with action ADD_QUESTION"&gt;&lt;/a&gt;  &lt;/p&gt;
Trying to pass string as payload ADD_QUESTION



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4y4ijyobl3w4vbrmmnpx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4y4ijyobl3w4vbrmmnpx.png" alt="Intellisense and autocompletion with TypeScript"&gt;&lt;/a&gt; &lt;/p&gt;
Intellisense and auto-completion with TypeScript

 

&lt;h4&gt;
  
  
  Using this we can add more actions for:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Updating the title of the question&lt;/li&gt;
&lt;li&gt;Deleting a question from array&lt;/li&gt;
&lt;li&gt;Sorting the questions&lt;/li&gt;
&lt;li&gt;Changing the type of the answer for a question.&lt;/li&gt;
&lt;li&gt;and more...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This may feel like typing extra for defining types, but it helps in narrowing the weird things that may happen during the runtime. Because JavaScript is just a weird language.&lt;/p&gt;

&lt;p&gt;So yeah that's how TypeScript makes development easier and accelerates developer productivity.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Vim 'navigation' basics</title>
      <dc:creator>ShUbHaM13M</dc:creator>
      <pubDate>Sun, 10 Sep 2023 08:36:03 +0000</pubDate>
      <link>https://forem.com/shubham13m/vim-navigation-basics-3062</link>
      <guid>https://forem.com/shubham13m/vim-navigation-basics-3062</guid>
      <description>&lt;p&gt;Learning Vim navigation can be a valuable skill for programmers, writers, and anyone who frequently works with text. It offers a unique approach to editing and navigating text that can significantly improve your productivity and efficiency.&lt;/p&gt;

&lt;p&gt;After learning just the basics of Vim navigation it will allow you to navigate, edit, and perform commands with unparalleled speed, effortlessly moving through code or text.&lt;/p&gt;

&lt;p&gt;You will be able to navigate and edit without constantly moving your hands away from the keyboard just to select a word or a whole paragraph.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;I started to explore ways to easily navigate using a keyboard only when my dad brought a laptop that had a broken touchpad.&lt;br&gt;
So I looked for ways to -&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open/close windows,&lt;/li&gt;
&lt;li&gt;Navigate by holding the Ctrl, Home, End,. etc keys&lt;/li&gt;
&lt;li&gt;Learning commands to start apps or shutdown.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;




&lt;p&gt;Alright to get started you can either install Vim in your operating system or you can just use an extension in Vs code which could be a good starting point Also you won't have to worry about how to exit Vim since you can just close Vs code directly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Installation of the Vim plugin &lt;/p&gt;
&lt;/blockquote&gt;


  


&lt;p&gt;Opening a new file now you will notice the cursor is changed&lt;br&gt;
And if you look at the status bar at the bottom you will notice &lt;strong&gt;-- Normal --&lt;/strong&gt; indicating that you are currently in the normal mode&lt;br&gt;
It is the default mode of Vim.&lt;br&gt;
It allows you to navigate the text, copy/cut/paste characters, words, and lines, but also roll-back actions, and so on.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Normal mode cursor&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--43oHKX7r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/ShUbHaM13M/vim-navigation-basics/master/resources/vim-normal-cursor.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--43oHKX7r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/ShUbHaM13M/vim-navigation-basics/master/resources/vim-normal-cursor.webp" alt="Normal mode cursor in Vim" width="505" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The status bar in Vs code indicating the current mode&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EbTXgrV---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/ShUbHaM13M/vim-navigation-basics/master/resources/vim-normal-mode.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EbTXgrV---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/ShUbHaM13M/vim-navigation-basics/master/resources/vim-normal-mode.webp" alt="Status bar indicating the current mode of Vim" width="583" height="199"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Basic Navigation
&lt;/h3&gt;

&lt;p&gt;You can use the keys:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
h to move left.&lt;/li&gt;
&lt;li&gt;
j to move up.&lt;/li&gt;
&lt;li&gt;
k to move down.&lt;/li&gt;
&lt;li&gt;
l to move right.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These key presses can be combined with numbers so&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
5j will move the cursor 5 lines down.&lt;/li&gt;
&lt;li&gt;
13l will move the cursor 13 characters to the left.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Navigating around the file using these keys might feel weird at first, but once you get a hang of it you will be able to navigate much quicker. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Navigating in Vscode using the Vim key-bindings &lt;/p&gt;
&lt;/blockquote&gt;


  
 
 

&lt;h4&gt;
  
  
  Some other key bindings that make navigating easier.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
w - Jump by the start of words&lt;/li&gt;
&lt;li&gt;
W - Jump by the start of words ignoring punctuations &lt;strong&gt;.&lt;/strong&gt; &lt;strong&gt;;&lt;/strong&gt;.., etc&lt;/li&gt;
&lt;li&gt;
e - Jump to the end of words&lt;/li&gt;
&lt;li&gt;
E - Jump to the end of words ignoring punctuations &lt;strong&gt;.&lt;/strong&gt; &lt;strong&gt;;&lt;/strong&gt;.., etc&lt;/li&gt;
&lt;li&gt;
b - Jump backward by words&lt;/li&gt;
&lt;li&gt;
B - Jump backward by words ignoring punctuations &lt;strong&gt;.&lt;/strong&gt; &lt;strong&gt;;&lt;/strong&gt;.., etc&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Again these keystrokes can be preceded by a number so&lt;br&gt;
&lt;code&gt;2w&lt;/code&gt; would jump two words ahead.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h4&gt;
  
  
  A Bit Advanced
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
0 - Jump to the start of the line&lt;/li&gt;
&lt;li&gt;
$ - Jump to the end of the line&lt;/li&gt;
&lt;li&gt;
G - Go to the bottom of the file.&lt;/li&gt;
&lt;li&gt;
gg - Go to the top of the file.&lt;/li&gt;
&lt;li&gt;
Ctrl + d - move down half a page.&lt;/li&gt;
&lt;li&gt;
Ctrl + u - move up half a page.&lt;/li&gt;
&lt;li&gt;
: {num} Enter - Go to that line number in the document.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you accidentally go into &lt;strong&gt;Insert&lt;/strong&gt; mode while having fun navigating the file using these newly learned powers, then just press Esc to go back to &lt;strong&gt;Normal&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That covers the basics of navigation using Vim. It may take a few days to get used to this new way of going through your files without using a mouse but it will make your workflow more productive and efficient.&lt;/p&gt;

</description>
      <category>vim</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
