<?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>DEV Community: Sawan Bhattacharya</title>
    <description>The latest articles on DEV Community by Sawan Bhattacharya (@kriptonian).</description>
    <link>https://dev.to/kriptonian</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%2F728503%2F99565eb8-d615-4fe0-959d-4131522dcde9.jpeg</url>
      <title>DEV Community: Sawan Bhattacharya</title>
      <link>https://dev.to/kriptonian</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kriptonian"/>
    <language>en</language>
    <item>
      <title>Why frontend developers don't wanna write e2e tests</title>
      <dc:creator>Sawan Bhattacharya</dc:creator>
      <pubDate>Tue, 13 Jan 2026 08:13:34 +0000</pubDate>
      <link>https://dev.to/kriptonian/why-frontend-developers-dont-wanna-write-e2e-tests-4j91</link>
      <guid>https://dev.to/kriptonian/why-frontend-developers-dont-wanna-write-e2e-tests-4j91</guid>
      <description>&lt;p&gt;If you have clicked on this article by reading the title, that means you are one of those frontend devs who hate writing tests, no worries, I am also one of you.&lt;/p&gt;

&lt;p&gt;Recently I came across a &lt;a href="https://martyhimmel.github.io/DEV-state-of-the-web-2018/" rel="noopener noreferrer"&gt;survey&lt;/a&gt; which showed that majority of the frontend teams don't write tests. That made me think, why is that, why is it that writing tests in frontend is mutually hated upon, and I came across these few points.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fklr01gykk6jzw55xlfx7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fklr01gykk6jzw55xlfx7.png" alt="DEV state of the web 2018" width="516" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is not just a rant, but I am also gonna talk about what kind of tests really matter and an easier option to write your tests fast.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Writing test is slow and involves too much boilerplate
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F4n3g73n736q1s04lb75y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F4n3g73n736q1s04lb75y.png" alt=" " width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most developers see writing tests as a chore rather than a benefit, and honestly, can you blame them? When the test file ends up having more lines of code than the actual feature you just built, something feels wrong.&lt;/p&gt;

&lt;p&gt;The biggest momentum killer is the boilerplate.&lt;/p&gt;

&lt;p&gt;Before you even get to the “user flow” you actually care about, you have to do a bunch of administrative work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You have to define the browser environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You have to mock the API calls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You have to handle authentication states (the classic “log in before every test” struggle).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the time you’ve finished setting the stage, you’ve forgotten what you were even trying to test in the first place. There’s no “quick way” to just record a flow and move on. Instead, you're stuck writing infrastructure code for a headless browser. It feels like you're building a “Shadow App” just to keep your real app in check—and that’s a massive time sink.&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Developers don't understand what to test
&lt;/h3&gt;

&lt;p&gt;If you’re working on the backend, testing is usually straightforward: you send an input, and you check if the database updated or the API returned the right JSON. It’s binary. It’s clean.&lt;/p&gt;

&lt;p&gt;But in the frontend? It’s a mess.&lt;/p&gt;

&lt;p&gt;When you finish a feature and sit down to write a test, a million questions pop up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do I test that the button is blue?&lt;/li&gt;
&lt;li&gt;Do I test that the loading spinner appears for exactly 200ms?&lt;/li&gt;
&lt;li&gt;Do I test the internal state of my React component, or just what the user sees?&lt;/li&gt;
&lt;li&gt;What happens if the API fails? Do I need a test for every single error toast?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For most of us, this leads to Analysis Paralysis. Since we don't have a clear “blueprint” of what matters, we either try to test everything (which leads to a maintenance nightmare) or we test nothing because we’re too overwhelmed to start.&lt;/p&gt;

&lt;p&gt;When you’ve just spent the last 6 hours wrestling with a complex UI feature, the last thing you want to do is spend another 3 hours playing a guessing game about which parts of the DOM are “important enough” to assert. It feels like throwing darts in the dark.&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Frontend moves faster than backend
&lt;/h3&gt;

&lt;p&gt;As we discussed before, frontend is not binary and straightforward like backend. Plus, the thing in the frontend moves a lot faster than it does in the backend. In the backend, an API contract rarely changes. But in the frontend, we’re constantly moving buttons, tweaking layouts, and renaming CSS classes to improve UX.&lt;/p&gt;

&lt;p&gt;So, when you make a “tiny” UI change that takes 2 minutes, your test suite suddenly breaks. You end up spending more time updating selectors and fixing “broken” tests than actually shipping features. Eventually, maintenance becomes such a headache that it’s easier to just stop writing them entirely so you can keep up with the pace of development.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why E2E tests matter
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fm2i3vdxsg9u8571q7sg2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fm2i3vdxsg9u8571q7sg2.png" alt=" " width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In frontend, E2E tests actually matter more than your unit tests. Think about it: you can have 100% test coverage on a button component, but that won't tell you if the API failed to load or if a transparent &lt;code&gt;div&lt;/code&gt; is accidentally covering the entire screen.&lt;/p&gt;

&lt;p&gt;At the end of the day, we only care about one thing: Is the user’s experience broken? E2E tests are the only ones that actually simulate a real person on a real device. They check if the “Happy Path” (like logging in or hitting 'Buy Now') actually works from start to finish. We hate writing them, but they’re the only reason we can click “Deploy” on a Friday afternoon and actually go home without worrying about a production meltdown.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with modern E2E testing
&lt;/h2&gt;

&lt;p&gt;You might be thinking, “But we have tools like Cypress and Playwright! Aren't they supposed to fix this?”&lt;/p&gt;

&lt;p&gt;They definitely made things better, but they didn’t solve the fundamental problem. Even with the “modern” stuff, we’re still running into the same brick walls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Flakiness Factor&lt;/strong&gt;: You run a test in CI, and it fails. You run it again without changing a single line of code, and it passes. T“flakiness”ess" destroys your trust. Is the code actually broken, or was the API just 50ms slower this time?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The “Shadow App” Maintenance&lt;/strong&gt;: As we talked about, these tools are still tied to your code. If you rename a class or change a data-testid, you have to go hunting through your test files to fix them. You're basically maintaining two apps at the same time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Learning Curve&lt;/strong&gt;: To use these “modern” tools properly, you have to learn about async/await patterns, complex locators, and how to handle headless browser contexts. It’s a lot to ask of a frontend dev who just wants to make sure their UI doesn't break.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, even the best frameworks today still feel like they were built for Automated Testers, not for Frontend Developers who need to move fast. They focus on how to test, but they don't help with the pain of keeping those tests alive.&lt;/p&gt;

&lt;h1&gt;
  
  
  Something to help you write E2E test faster
&lt;/h1&gt;

&lt;p&gt;After years of fighting with brittle selectors and spending more time in Cypress docs than in my actual codebase, I decided to build something better.&lt;/p&gt;

&lt;p&gt;I’m working on a tool called &lt;a href="https://github.com/kriptonian1/symphony" rel="noopener noreferrer"&gt;Symphony&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The goal of Symphony is simple: Make E2E testing feel like a natural part of the frontend workflow, not a second job. Instead of writing complex, imperative code to click buttons and wait for loaders, Symphony lets you define your user flows in a way that actually makes sense. It uses a YAML-based DSL—which basically means you describe your test steps in plain, human-readable English.&lt;/p&gt;

&lt;p&gt;Here is why I think it’s a game-changer for devs like us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Zero Boilerplate&lt;/strong&gt;: No more setting up browser contexts or massive beforeEach blocks. You just define the flow and run it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built for Speed&lt;/strong&gt;: It’s designed to be fast to write. If it takes you 2 minutes to build a feature, it shouldn't take you 20 minutes to test it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Readable by Anyone&lt;/strong&gt;: Because the tests are written in a simple YAML format, even a PM or a designer can look at the test file and understand exactly what is being covered.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Symphony is built for the "lazy" developer (the best kind of developer) who wants the safety of E2E tests without the nightmare of maintenance.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>testing</category>
      <category>discuss</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Understanding Conditional TypeScript Props: Building Adaptable Components</title>
      <dc:creator>Sawan Bhattacharya</dc:creator>
      <pubDate>Sun, 23 Jul 2023 15:41:49 +0000</pubDate>
      <link>https://dev.to/kriptonian/understanding-conditional-typescript-props-building-adaptable-components-358</link>
      <guid>https://dev.to/kriptonian/understanding-conditional-typescript-props-building-adaptable-components-358</guid>
      <description>&lt;p&gt;Have you ever come across situations where certain properties of a component should only appear under specific conditions or when particular data is provided? This can be a real challenge, but fear not! TypeScript offers a nifty feature called 'conditional types' that can help us deal with such scenarios effectively. In this blog, we'll explore how conditional TypeScript props allow us to control the availability of properties based on different conditions, making our components more adaptable and secure. Let's dive in and discover the magic of TypeScript's conditional types!&lt;/p&gt;

&lt;p&gt;To achieve this, TypeScript provides two primary ways: types and interfaces. In this blog, we'll start by exploring conditional types using &lt;code&gt;types&lt;/code&gt;, and later, we'll dive into &lt;code&gt;interfaces&lt;/code&gt; to further enrich our understanding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conditional props using &lt;code&gt;types&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Let's say you are making a component called &lt;code&gt;Shape&lt;/code&gt; where we can define the id, colour, type of shape, and their dimensions, and according to that it's going to render out the shape.&lt;/p&gt;

&lt;p&gt;Here is the component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Prop&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;typeShape&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;typeShape&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;circle&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
                &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;rem`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;rem`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`1000px`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`center`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`center`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`flex`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                Circle
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;typeShape&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;square&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sideLength&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
                &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sideLength&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;rem`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sideLength&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;rem`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`center`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`center`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`flex`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                Square
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;typeShape&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rectangle&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
                &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;rem`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;rem`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`center`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`center`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`flex`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                Rectangle
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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;So for this component, if we have to define a type, then this is how most of us will write it&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;Prop&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;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&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;typeShape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;circle&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;square&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;rectangle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;sideLength&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&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;The current problem with this type definition is that if the &lt;code&gt;typeShape&lt;/code&gt; is set to "circle", it allows the usage of properties like &lt;code&gt;width&lt;/code&gt; or &lt;code&gt;sideLength&lt;/code&gt; in addition to the expected &lt;code&gt;radius&lt;/code&gt;, because we have defined this property optional. This flexibility can lead to potential errors, and it's not as clear which properties are valid for a particular shape.&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%2Fifom1ye03pecjdw3qt5e.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%2Fifom1ye03pecjdw3qt5e.png" alt="code with no type error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To fix this, we are going to take leverage of &lt;a href="https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types" rel="noopener noreferrer"&gt;union type&lt;/a&gt; in TypeScript. Union types allow us to combine multiple types into a single type, giving us the flexibility to represent a value that can be one of several types.&lt;/p&gt;

&lt;p&gt;In our case, we are going to use union types to construct a more refined type definition for the Prop type. The common part of the type have properties &lt;code&gt;id&lt;/code&gt;, and &lt;code&gt;color&lt;/code&gt;. We then utilize the &lt;code&gt;&amp;amp;&lt;/code&gt; (intersection) operator to combine this base type with different conditional types, each corresponding to a specific shape.&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;Props&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;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&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;&amp;amp;&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;typeShape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;circle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;typeShape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;sideLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;typeShape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rectangle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;Now you can see that the editor is throwing an error, which says &lt;code&gt;Type '{ id: number; typeShape: "circle"; radius: number; color: string; width: number; sideLength: number; }' is not assignable to type 'IntrinsicAttributes &amp;amp; Props'.&lt;br&gt;
  Property 'width' does not exist on type 'IntrinsicAttributes &amp;amp; { id: number; color: string; } &amp;amp; { typeShape: "circle"; radius: number; }'.&lt;/code&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%2Fn7iynwjqz9e7srwx8l1x.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%2Fn7iynwjqz9e7srwx8l1x.png" alt="Code throwing error after changing the type"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is precisely what we aimed to achieve with the implementation of conditional types. By using conditional types, we have transformed our type system, making it more precise and reliable. TypeScript's static analysis capabilities enhance our development experience and promote the creation of robust and type-safe components.&lt;/p&gt;

&lt;p&gt;The error message demonstrates that TypeScript recognizes the specific shape-related properties that should be allowed for each shape type. In this case, it correctly enforces that &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;sideLength&lt;/code&gt; properties are not allowed for the "circle" shape, and the correct property for a "circle" shape is &lt;code&gt;radius&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conditional props using &lt;code&gt;interface&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Now let's explore how we can achieve the same result using interfaces. Interfaces are another essential feature of TypeScript that allows us to define custom types and object shapes. Similar to types, interfaces provide a way to create reusable type definitions for our components and data structures.&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;IShape&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;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ICircle&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;IShape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;typeShape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;circle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ISquare&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;IShape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;typeShape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;sideLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IRectangle&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;IShape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;typeShape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rectangle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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, the extends keyword acts as an intersection (&amp;amp;), effectively creating a relationship where the properties of IShape will be shared across all other shape interfaces.&lt;/p&gt;

&lt;p&gt;By using extends, we establish a connection between the base IShape interface and the shape-specific interfaces (ICircle, ISquare, and IRectangle). This relationship ensures that all shape interfaces inherit the properties defined in IShape (id and color).&lt;/p&gt;

&lt;p&gt;Now to make it optional, we have to use union in the component prop&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ICircle&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;ISquare&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;IRectangle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// body will be same&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In conclusion, we have achieved conditional props with &lt;code&gt;interfaces&lt;/code&gt;, just like we did with &lt;code&gt;types&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>react</category>
    </item>
    <item>
      <title>Making Life Easy with Makefile: Streamlining Software Development for Beginners</title>
      <dc:creator>Sawan Bhattacharya</dc:creator>
      <pubDate>Sun, 14 May 2023 16:29:07 +0000</pubDate>
      <link>https://dev.to/kriptonian/making-life-easy-with-makefile-streamlining-software-development-for-beginners-1m6c</link>
      <guid>https://dev.to/kriptonian/making-life-easy-with-makefile-streamlining-software-development-for-beginners-1m6c</guid>
      <description>&lt;p&gt;Anyone who's spent time in software development knows the tedium of writing and executing repeated commands for testing and building applications. It's a time-consuming process that can feel like running on a hamster wheel. But what if there was a way to streamline this process, automate these repeated tasks, and ultimately make your life as a developer easier? Enter the world of Makefiles.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Makefile? And How Is It Useful?
&lt;/h2&gt;

&lt;p&gt;A Makefile is a text file that contains a list of commands to be executed, along with rules that specify when those commands should be executed. Makefiles are used to automate the process of building software projects. We need to use the command &lt;code&gt;make &amp;lt;target_name&amp;gt;&lt;/code&gt; to execute our makefile. &lt;/p&gt;

&lt;p&gt;Consider a common scenario in software development: before committing any changes, you want to ensure that all tests pass and that no build failures exist. In such a case, a Makefile can become an invaluable tool. This file should contain all the necessary commands related to testing and building your project.&lt;/p&gt;

&lt;p&gt;To automate this process, you simply need to invoke your targets using the &lt;code&gt;make &amp;lt;target_name&amp;gt;&lt;/code&gt; command within your git hooks. This action triggers the commands specified in the Makefile, executing your tests and checking for build errors.&lt;/p&gt;

&lt;p&gt;The beauty of this approach lies in its automation. Instead of manually running tests and checking for build failures every time you commit changes, the process becomes a part of your git workflow, which means it’s going to run your tests and builds every time before committing the changes. This not only makes the development process more efficient, but also ensures consistent quality checks before any changes are committed to your codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write your first Makefile
&lt;/h2&gt;

&lt;p&gt;Let's start by writing the classic  'Hello, World!' program.  Begin by creating a new file named Makefile. Inside this file, insert the following code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;

&lt;span class="nl"&gt;hello&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"hello world 👋"&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, open your terminal and execute the &lt;code&gt;make&lt;/code&gt; command. You'll be greeted with the familiar output, as shown in the screenshot below:&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%2Flf9m99j21vsd8njskq3i.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%2Flf9m99j21vsd8njskq3i.png" alt="output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulation 🎉 you just created your first make file. Now, let's break down what we just did and understand how the syntax of makefile works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Makefile Syntax
&lt;/h2&gt;

&lt;p&gt;In makefile, we have the following syntax structure&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

target: prerequisites
    recipe


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let’s see what each of these parts does &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;target&lt;/code&gt; can be thought of as a task or a goal that you want to accomplish, Typically, a target is the name of a file that is generated by a program, like an executable or object file. However, a target can also be the name of an action to carry out, such as clean. Like in the previous example, &lt;code&gt;hello&lt;/code&gt; was a target.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;prerequisites&lt;/code&gt;  this basically says what file if needed to be run before running the &lt;code&gt;target&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;recipe&lt;/code&gt; this is the command you want to run
One thing that you must have noticed that whenever you run the target it outputs the &lt;code&gt;recipe&lt;/code&gt; before running it this gets a bit annoying so to stop this from happening you need to add &lt;code&gt;@&lt;/code&gt; before the command
```makefile
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;hello:&lt;br&gt;
    &lt;a class="mentioned-user" href="https://dev.to/echo"&gt;@echo&lt;/a&gt; "hello world 👋"&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 &amp;gt; Important: If you simply run make without specifying a target, it defaults to executing the first target listed in the Makefile.

## Let's See This in Action
The best way to solidify our understanding is through practical examples. So, let's apply our knowledge by creating a small Go program. Firstly, make a file and name it `main.go` and add this code inside it
```go


package main

import "fmt"

func add(x, y int) int {
   return x + y
}

func main() {
   fmt.Println(add(1, 2))
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Next, let's write a test to verify if this code functions correctly. Create a new file named &lt;code&gt;main_test.go&lt;/code&gt; and add the following code: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="s"&gt;"testing"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

   &lt;span class="n"&gt;originalOutput&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;originalOutput&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1 + 2 = 3"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Expected 3, got %d instead"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;originalOutput&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;Now, let's automate the building and testing process using a Makefile. Create a new file named &lt;code&gt;Makefile&lt;/code&gt; and add the following contents:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;

&lt;span class="nv"&gt;FILENAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;main.go


&lt;span class="nl"&gt;all&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;run build test&lt;/span&gt;


&lt;span class="nl"&gt;run&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;./bin/main


&lt;span class="nl"&gt;build&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;go build &lt;span class="nt"&gt;-o&lt;/span&gt; bin/ &lt;span class="p"&gt;$(&lt;/span&gt;FILENAME&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nl"&gt;test&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;go &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; ./...


&lt;span class="nl"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; bin/


&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;all run build test clean&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's break down how the Makefile works, line by line. The FILENAME variable is used to store the name of our Go file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;all&lt;/code&gt;: The default target. It depends on the targets run, build, and test, which will be executed in sequence.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;run&lt;/code&gt;: The target responsible for running our program. It depends on the build target and executes the ./bin/main command to run the compiled executable.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt;: This target compiles our Go code into an executable. The -o bin/ option specifies the output directory for the binary file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;test&lt;/code&gt;: The target to run our tests. It executes go test -v ./... to run all tests in the current directory and its subdirectories.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;clean&lt;/code&gt;: The target to clean up the generated files. It removes the bin/ directory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.PHONY&lt;/code&gt;: This special target declares other targets as phony, meaning they are not actual files but rather commands or actions.
Now you're ready to run &lt;code&gt;make&lt;/code&gt; in your terminal, and it will automate the build, test, and run processes for your Go program. &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;TIPS: If you wanna change your default target then you have to use &lt;code&gt;.DEFAULT_GOAL := &amp;lt;target_name&amp;gt;&lt;/code&gt;&lt;br&gt;
Example, if you add &lt;code&gt;.DEFAULT_GOAL := build&lt;/code&gt; to the makefile we just created and run then command &lt;code&gt;make&lt;/code&gt; then it’s gonna run &lt;code&gt;build&lt;/code&gt; and not the &lt;code&gt;all&lt;/code&gt; target&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Some Advance Stuffs
&lt;/h2&gt;

&lt;p&gt;If you're ready to dive deeper into the world of Makefiles, this section is for you. Here, we'll explore some more advanced techniques and concepts to help you tackle complex scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  Change Default Shell
&lt;/h3&gt;

&lt;p&gt;To change the default shell used in a Makefile, you can specify the desired shell by setting the SHELL variable. For instance, if you want to use Bash as the default shell, you can define it as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

SHELL=/bin/bash

myshell:
    echo $0


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this example, we set the &lt;code&gt;SHELL&lt;/code&gt; variable to /bin/bash. Now, when you run the&lt;code&gt;myshell&lt;/code&gt; target, it will execute the &lt;code&gt;echo $0&lt;/code&gt; command using Bash as the default shell.&lt;/p&gt;

&lt;p&gt;By adjusting the&lt;code&gt;SHELL&lt;/code&gt; variable, you can customize the shell environment to suit your preferences or meet specific requirements for your Makefile.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conditional Statement
&lt;/h3&gt;

&lt;p&gt;Conditional statements in Makefiles provide a powerful mechanism for executing different commands based on specific conditions. They enable you to tailor the build process according to the environment, variables, or user-defined values. Let's explore an example of how to write conditional statements in a Makefile:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

foo = ok

all:
ifeq ($(foo), ok)
    echo "foo equals ok"
else
    echo "nope"
endif


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this example, we have a variable &lt;code&gt;foo&lt;/code&gt; with the value ok. The &lt;code&gt;ifeq&lt;/code&gt; statement checks if the value of $(foo) is equal to ok. If the condition is true, the command echo "foo equals ok" is executed. Otherwise, the command echo "nope" is executed.&lt;/p&gt;

&lt;p&gt;When you run make all in the terminal, it will evaluate the conditional statement and execute the appropriate command based on the value of foo. In this case, it will print foo equals ok.&lt;/p&gt;

&lt;h3&gt;
  
  
  Functions in Makefile
&lt;/h3&gt;

&lt;p&gt;Functions in Makefiles play a crucial role in writing modular and reusable code. They allow you to encapsulate commands and parameters into named functions, promoting code organization and reducing duplication. Here's how functions are structured in Makefiles:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

define &amp;lt;function_name&amp;gt;
    # Function body ...
    echo "$(1) $(2) $(3) ..." # Parameters passed
endef

funcCall:
    $(call &amp;lt;function_name&amp;gt;, &amp;lt;param1&amp;gt;, &amp;lt;param2&amp;gt;, ...)



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here, we define a user-defined function with the name  using the &lt;code&gt;define&lt;/code&gt; directive. The function body consists of the desired commands or operations. Within the function body, you can reference parameters passed to the function using $(1), $(2), $(3), and so on.&lt;/p&gt;

&lt;p&gt;To invoke the user-defined function, you use the call directive followed by the function name and its respective parameters.&lt;/p&gt;

&lt;p&gt;Let's see an example that demonstrates the usage of user-defined functions and their invocation:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

define foo
    echo "launch 🚀"
endef

define uff
    echo “hey $(1) 👋”
endef

 fooCall:
    @$(call foo)
uffCall:
    @$(call uff, “John Doe”)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this example, we define two user-defined functions: foo and uff. The uff function takes a parameter, which we pass as "John Doe". To call these functions, we use the call directive followed by the function name. Running this code will produce the following output:&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%2Fj0jcla3t2nw06l72oxwd.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%2Fj0jcla3t2nw06l72oxwd.png" alt="markdown function output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also import functions from other makefile using &lt;code&gt;include&lt;/code&gt; directive, the syntax is &lt;code&gt;include &amp;lt;fille1&amp;gt; &amp;lt;fille2&amp;gt; &amp;lt;fille3&amp;gt; …&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have learned the power of Makefiles in automating testing and building processes in software development. By utilizing Makefiles, developers can streamline their workflows, save time, and ensure consistent quality checks.&lt;/p&gt;

&lt;p&gt;If you want to explore further and dive deeper into the world of Makefiles, I recommend referring to the official GNU Make manual available at &lt;a href="https://www.gnu.org/software/make/manual/make.pdf" rel="noopener noreferrer"&gt;https://www.gnu.org/software/make/manual/make.pdf&lt;/a&gt;. This comprehensive resource provides in-depth information on Makefile syntax, advanced techniques, and best practices.&lt;/p&gt;

&lt;p&gt;Feel free to connect with me on social media &lt;a href="https://www.linkedin.com/in/sawan-bhattacharya/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; to stay updated on the latest software development tips, tricks, and insights.&lt;/p&gt;

&lt;p&gt;Happy coding 👨‍💻&lt;/p&gt;

</description>
      <category>programming</category>
      <category>devops</category>
      <category>automation</category>
      <category>cli</category>
    </item>
  </channel>
</rss>
