<?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: Matías Hernández Arellano</title>
    <description>The latest articles on Forem by Matías Hernández Arellano (@matiasfha).</description>
    <link>https://forem.com/matiasfha</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%2F465403%2F25305d44-10cd-4090-86c0-ecfcb62fb949.jpeg</url>
      <title>Forem: Matías Hernández Arellano</title>
      <link>https://forem.com/matiasfha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/matiasfha"/>
    <language>en</language>
    <item>
      <title>Advanced Git Commands and Workflows: A Comprehensive Guide for Developers</title>
      <dc:creator>Matías Hernández Arellano</dc:creator>
      <pubDate>Wed, 06 Sep 2023 05:51:28 +0000</pubDate>
      <link>https://forem.com/documatic/advanced-git-commands-and-workflows-a-comprehensive-guide-for-developers-5865</link>
      <guid>https://forem.com/documatic/advanced-git-commands-and-workflows-a-comprehensive-guide-for-developers-5865</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;In software development, Git is more than just a tool—it's an essential lifeline for developers. It's the cornerstone of version control, allowing multiple people to work on a project without stepping on each other's toes. While the basic commands lay the groundwork, the advanced commands and workflows constitute the building blocks that add robustness to your version control capabilities. This article is your architectural blueprint to these building blocks, designed specifically for mid-senior engineers and engineering managers who are ready to elevate their Git proficiency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deep Dive into Advanced Git Commands
&lt;/h2&gt;

&lt;p&gt;In this section, we will delve into some of the advanced Git commands that can make your life as a developer more manageable and more efficient. We'll explore commands like interactive rebase, cherry-pick, bisect, reflog, and blame. Each command serves a unique purpose and can help you in different scenarios. Let's look at these commands, how they work, and where they can be helpful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interactive Rebase
&lt;/h3&gt;

&lt;p&gt;Picture Git as a time machine. The interactive rebase command is the control panel of this machine, enabling you to travel back in time, alter the events (commits), and proceed along the new timeline. It's a powerful tool that gives you complete control over your commit history. For instance, if you're working on a feature with a messy commit history, you can use interactive rebase to clean it up, making it more understandable for your team.&lt;/p&gt;

&lt;p&gt;Here's how you can do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start an interactive rebase&lt;/span&gt;
git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; HEAD~3

&lt;span class="c"&gt;# Text editor opens up for you to modify the commits&lt;/span&gt;
&lt;span class="c"&gt;# You can change the order of the commits, squash them together, or even delete them&lt;/span&gt;
&lt;span class="c"&gt;# Save and close the editor to start the rebase&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interactive rebase command opens up a text editor where you can see a list of the commits that you're about to rewrite. The commits are displayed in reverse order, with the oldest commit at the top. You can change the order of the commits, squash them together, or even delete them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cherry-pick
&lt;/h3&gt;

&lt;p&gt;Visualize picking apples from a tree, but you desire only the ripest ones. The cherry-pick command is your tool for this task. It lets you choose a commit from a branch (the tree) and apply it to another. This is handy when you've fixed a bug in a development branch and must use the fix in the production branch without integrating any other changes.&lt;/p&gt;

&lt;p&gt;Here's an example of how to use cherry-pick:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Cherry-pick a commit&lt;/span&gt;
git cherry-pick &amp;lt;commit-hash&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cherry-pick command applies the changes introduced by the commit with the provided hash onto the current branch. This can be particularly useful when applying a bug fix from the development branch to the production branch without merging the entire branch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bisect
&lt;/h3&gt;

&lt;p&gt;Hunting for a bug in a commit is akin to finding a needle in a haystack. The bisect command is your high-tech metal detector. By marking a good commit (no needle) and a bad commit (with a needle), Git bisect will guide you to the offending commit most efficiently.&lt;/p&gt;

&lt;p&gt;Here's how you can use bisect to find a bug:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start a bisect session&lt;/span&gt;
git bisect start

&lt;span class="c"&gt;# Mark the current state as bad&lt;/span&gt;
git bisect bad

&lt;span class="c"&gt;# Mark the last known good state&lt;/span&gt;
git bisect good &amp;lt;commit-hash&amp;gt;

&lt;span class="c"&gt;# Git guides you to the offending commit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The bisect command uses a binary search algorithm to find the commit that introduced a bug. It's a powerful tool that can save you a lot of time when trying to track down a bug.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reflog
&lt;/h3&gt;

&lt;p&gt;If Git is a time machine, then reflog is the black box recorder. It keeps track of all the time travel you've done. Did you accidentally delete a branch? No worries, Reflog has got you covered.&lt;/p&gt;

&lt;p&gt;Here's how you can use reflog:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# See the reflog&lt;/span&gt;
git reflog

&lt;span class="c"&gt;# Recover a lost commit&lt;/span&gt;
git checkout &amp;lt;commit-hash&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reflog command shows you a list of all the actions that you've taken in the Git repository. It's a powerful tool that can save you from disastrous mistakes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Blame
&lt;/h3&gt;

&lt;p&gt;The blame command is akin to a detective that helps you trace back the origins of every line in a file. It's a potent tool when you're trying to comprehend why a particular line of code was added, who did it, and when.&lt;/p&gt;

&lt;p&gt;Here's how you can use blame:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Use blame on a file&lt;/span&gt;
git blame &amp;lt;file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The blame command shows an annotation of the file, with information about which commit last modified each line. This can be extremely useful when trying to understand a file's history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring Advanced Git Workflows
&lt;/h2&gt;

&lt;p&gt;In this section, we will explore some advanced Git workflows that can help you manage your projects more efficiently. We'll look at the Gitflow Workflow, the Forking Workflow, and the Feature Branch Workflow. Each of these workflows has its strengths and can be useful in different scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gitflow Workflow
&lt;/h3&gt;

&lt;p&gt;Picture managing a bustling city. The Gitflow Workflow is your city planning guide. The main and develop branches are akin to the city's main arteries. Feature, release, and hotfix branches are the smaller streets that feed into these main arteries. This workflow ensures that traffic (changes) flows smoothly, no matter how busy it gets.&lt;/p&gt;

&lt;p&gt;Here's an example of how you can use Gitflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start a new feature&lt;/span&gt;
git flow feature start &amp;lt;feature&amp;gt;

&lt;span class="c"&gt;# Finish the feature&lt;/span&gt;
git flow feature finish &amp;lt;feature&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Gitflow Workflow is a robust workflow that's well-suited for managing large projects. It uses two parallel long-lived branches to record the history of the project: the Main branch for production-ready code and the developer branch for integration of features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Forking Workflow
&lt;/h3&gt;

&lt;p&gt;This is like a potluck dinner. Everyone brings (forks) their dish (repository), makes changes (adds their secret sauce), and then offers it to the host (original repository) for inclusion.&lt;/p&gt;

&lt;p&gt;Here's how you can contribute to a project using the Forking Workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the forked repository&lt;/span&gt;
git clone &amp;lt;repository&amp;gt;

&lt;span class="c"&gt;# Make changes and commit them&lt;/span&gt;
git commit &lt;span class="nt"&gt;-am&lt;/span&gt; &lt;span class="s2"&gt;"made some changes"&lt;/span&gt;

&lt;span class="c"&gt;# Push changes to your fork&lt;/span&gt;
git push origin main

&lt;span class="c"&gt;# Open a pull request on GitHub&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Forking Workflow is commonly used in open-source projects. It allows anyone to contribute to the project without access to the central repository. The changes are proposed using a pull request, which can be reviewed and discussed before being merged into the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Feature Branch Workflow
&lt;/h3&gt;

&lt;p&gt;Think of your codebase as a museum exhibit. The main branch is the exhibit open to the public. Feature branches are the artists' studios where new exhibits (features) are prepared.&lt;/p&gt;

&lt;p&gt;Here's how you can add a new feature using the Feature Branch Workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start a new feature&lt;/span&gt;
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; &amp;lt;feature&amp;gt;

&lt;span class="c"&gt;# Make changes and commit them&lt;/span&gt;
git commit &lt;span class="nt"&gt;-am&lt;/span&gt; &lt;span class="s2"&gt;"add new feature"&lt;/span&gt;

&lt;span class="c"&gt;# Switch to the main branch&lt;/span&gt;
git checkout main

&lt;span class="c"&gt;# Merge the feature into the master&lt;/span&gt;
git merge &amp;lt;feature&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Feature Branch Workflow is a simple workflow that's great for solo developers and small teams. It uses small, focused branches to develop new features or fix bugs. This keeps the main branch clean and your code base stable.&lt;/p&gt;

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

&lt;p&gt;Mastering Git's advanced commands and workflows is akin to unlocking a new level in a game. It opens up new possibilities and new ways to control and manage your code. Whether you're navigating the intricate history of a long-lived project or coordinating a major release, these tools offer the control and flexibility needed to handle complex scenarios. So, dive in, explore, and level up your Git game.&lt;/p&gt;

&lt;p&gt;Here's how you can add a new feature using the Feature Branch Workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start a new feature&lt;/span&gt;
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; &amp;lt;feature&amp;gt;

&lt;span class="c"&gt;# Make changes and commit them&lt;/span&gt;
git commit &lt;span class="nt"&gt;-am&lt;/span&gt; &lt;span class="s2"&gt;"add new feature"&lt;/span&gt;

&lt;span class="c"&gt;# Switch to the main branch&lt;/span&gt;
git checkout main

&lt;span class="c"&gt;# Merge the feature into the master&lt;/span&gt;
git merge &amp;lt;feature&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Feature Branch Workflow is a simple workflow that's great for solo developers and small teams. It uses small, focused branches to develop new features or fix bugs. This keeps the main branch clean and your code base stable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mastering Git's advanced commands and workflows is akin to unlocking a new level in a game. It opens up new possibilities and new ways to control and manage your code. Whether you're navigating the intricate history of a long-lived project or coordinating a major release, these tools offer the control and flexibility needed to handle complex scenarios. So, dive in, explore, and level up your Git game.&lt;/p&gt;

</description>
      <category>git</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Using SoundScribe to Maximize Your Writing Productivity</title>
      <dc:creator>Matías Hernández Arellano</dc:creator>
      <pubDate>Wed, 12 Jul 2023 00:50:57 +0000</pubDate>
      <link>https://forem.com/soundscribe/using-soundscribe-to-maximize-your-writing-productivity-2bll</link>
      <guid>https://forem.com/soundscribe/using-soundscribe-to-maximize-your-writing-productivity-2bll</guid>
      <description>&lt;p&gt;As a content creator, every second of your day counts. Each moment is an opportunity to create, expand, and refine your ideas. Let's face it though, writing is time-consuming. Between formatting, grammar checks, and the ever-present specter of writer’s block, transforming your ideas into engaging content can often feel like an uphill trek. But what if you had a powerful tool, an AI-powered system called SoundScribe, designed to streamline the process?&lt;/p&gt;

&lt;p&gt;Rather than staring at a blank page as minutes tick by, &lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt; allows you to record your thoughts directly into your browser. Just speak, and allow the system to capture those ideas as they spring into existence. Not just ideas recorded within your workspace, either. With an upcoming mobile app feature, you can capture those bursts of creativity wherever inspiration strikes, ensuring no idea slips away unnoticed.&lt;/p&gt;

&lt;p&gt;But &lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt; doesn't just transcribe. Taking its support a notch higher, it leverages AI technology to analyze the tone and pacing of your speech. The process feels as natural and swift as having a conversation with a friend, free-flowing and unscripted. Yet, in your words and speech, our system identifies the unique cadences that differentiate your voice, ensuring that your essence is not lost in the transition from the spoken to the written word.&lt;/p&gt;

&lt;p&gt;The result: a draft rich with your own distinctive touches, that only needs a final layer of polish before it's ready for your audience. It won't be surprising if you find your content production process becoming much more efficient.&lt;/p&gt;

&lt;p&gt;So, how can you integrate &lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt; into your existing writing routine? Start by recording quick thoughts as they come to you, then let &lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt; handle the transcription in the background. You can return to the tool whenever you choose, to find your thoughts transcribed and waiting for you.&lt;/p&gt;

&lt;p&gt;This is where you come in to add the finishing touches. Delete parts that don't work, expand on interesting points, and make sure everything is in the right place. Think of &lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt; as a virtual writing partner that never tires, ready to listen and capture your thoughts at a moment's notice.&lt;/p&gt;

&lt;p&gt;In essence, &lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt; combines the freedom of conversation with the discipline of writing. It takes care of the heavy lifting, transcribing and organizing your spoken thoughts so that you can focus on the big picture – refining and polishing your narratives into compelling, high-quality content.&lt;/p&gt;

&lt;p&gt;Jumpstart your writing productivity today with SoundScribe because every word matters and every moment counts.&lt;/p&gt;

&lt;p&gt;Join to &lt;a href="https://soundscribe.app"&gt;the waitlist now&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>soundscribe</category>
      <category>ai</category>
      <category>contentwriting</category>
      <category>writing</category>
    </item>
    <item>
      <title>Breaking Down the Writing Barriers with SoundScribe</title>
      <dc:creator>Matías Hernández Arellano</dc:creator>
      <pubDate>Tue, 11 Jul 2023 20:35:53 +0000</pubDate>
      <link>https://forem.com/soundscribe/breaking-down-the-writing-barriers-with-soundscribe-303b</link>
      <guid>https://forem.com/soundscribe/breaking-down-the-writing-barriers-with-soundscribe-303b</guid>
      <description>&lt;p&gt;Writing is an art, a medium of expression that paves the way for communication and sharing ideas. But at times, the process of writing can be daunting. The blank, expectant page waiting for our thoughts to spill onto it can be intimidating, even paralyzing. As a writer, the dreaded writer's block is an all-too-familiar monster, creeping in when you least expect it, transforming that initial spark of creativity into a frustrating exercise in futility. It was during one of these instances when the idea behind &lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt;, a revolutionary AI-powered transcription and writing tool, first came to life.&lt;/p&gt;

&lt;p&gt;Speaking my thoughts always came naturally and faster to me, as it does for many people. There is fluidity in speech that is often hard to capture in writing. Plus, conversing directly with your device takes less time than having to type out every idea. The simple act of recording audio, dictating lines of thought directly into a browser, sparked the genesis of what &lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt; is today. Initially, it was a way for me to simplify my note-taking, to turn my spoken words into a pool of ideas that could be molded further into a more structured form. But it soon evolved into much more – a tool to aid with content creation itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt; was born out of a need – a need for a tool that would allow us to keep content creation simple, straightforward, and effective, a need to overcome the barriers that often make the writing process seem unnerving. Traditional transcription services usually stop at converting audio-to-text, but &lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt; sought to do more.&lt;/p&gt;

&lt;p&gt;Offering more than mere transcription, &lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt; seizes the ideas within your spoken words and transforms them into a variety of engaging written content. The ease of use when recording thoughts directly in the browser and the swift transcription that follows, provides an effortless leap from thought to textual format, ultimately breaking down the wall that many writers face.&lt;/p&gt;

&lt;p&gt;Though still under heavy development, &lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt; already shows its potential to simplify and redefine my content creation process. But the vision for SoundScribe spans beyond individual use. It's not about changing the way one person writes. It's about revolutionizing the entire writing process for everyone who has ever wanted to share their ideas with the world.&lt;/p&gt;

&lt;p&gt;In essence, &lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt; is not merely a tool, but a companion for creators. It’s a bridge connecting one's creative thought process with the digital world, aiming to assist content creators, from blogs to research articles, social media posts to in-depth reports. The vision is clear; to provide a one-step solution that takes creators from idea to content, simplifying the journey and letting them focus on refining their narrative.&lt;/p&gt;

&lt;p&gt;Explore the potential of &lt;a href="https://soundscribe.app"&gt;Soundscribe&lt;/a&gt;. Overcome writing barriers with the power of your voice. Bypass writer's block, simplify your content creation process, and let your ideas flow in the way human expressions are most genuine: through speech.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>contentwriting</category>
    </item>
    <item>
      <title>How to Use Static Code Analysis Tools to Improve Your TypeScript Codebase</title>
      <dc:creator>Matías Hernández Arellano</dc:creator>
      <pubDate>Mon, 12 Jun 2023 13:15:44 +0000</pubDate>
      <link>https://forem.com/documatic/how-to-use-static-code-analysis-tools-to-improve-your-typescript-codebase-b6g</link>
      <guid>https://forem.com/documatic/how-to-use-static-code-analysis-tools-to-improve-your-typescript-codebase-b6g</guid>
      <description>&lt;h1&gt;
  
  
  How to Use Static Code Analysis Tools to Improve Your TypeScript Codebase
&lt;/h1&gt;

&lt;p&gt;Static code analysis tools can revolutionize how you write and maintain your TypeScript codebase. As a senior JavaScript or TypeScript engineer, team leader, or engineering leader, leveraging these tools is critical to optimizing your codebase's quality, maintainability, and scalability. In this article, we will explore different static code analysis tools, and how to introduce them into your TypeScript codebase and use them effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Static Code Analysis?
&lt;/h2&gt;

&lt;p&gt;Before we dive into static code analysis tools' applications and benefits, let's first define what static code analysis means. Static code analysis is the process of examining your code without executing it. This evaluation focuses on code structure, syntax, semantics, and other factors helping you identify potential bugs, performance issues, security vulnerabilities, and more.&lt;/p&gt;

&lt;p&gt;For instance, static code analysis can help you find and fix issues early in the development cycle, reduce technical debt, improve code consistency, and avoid errors and bugs commonly encountered in complex applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Using Static Code Analysis Tools in a TypeScript Codebase
&lt;/h2&gt;

&lt;p&gt;Implementing static code analysis tools in your TypeScript codebase can enhance your team's productivity, code maintainability, and consistency. Here are some benefits that you can achieve with these tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improve Code Quality: Code analysis detects common coding issues that would otherwise remain unnoticed during development and deployment.&lt;/li&gt;
&lt;li&gt;Enhance Consistency: By helping enforce coding standards, your team can work more effectively and reduce time spent debugging the code.&lt;/li&gt;
&lt;li&gt;Save Time and Cost: The earlier you can solve issues, the less expensive they are to address.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Choose Static Code Analysis Tools for TypeScript Codebases
&lt;/h2&gt;

&lt;p&gt;Several static code analysis tools are designed for TypeScript codebases that provide type-checking, customizations, integrations, and reports. Choosing the right tool begins with understanding your unique needs and preferences. However, these key factors are good to consider when selecting these tools:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Support for TypeScript&lt;/strong&gt;: Ensure the tool is compatible with TypeScript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customization&lt;/strong&gt;: Can you customize the tool to fit your project requirements?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration&lt;/strong&gt;: Will it integrate smoothly with your project's current workflow?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reports&lt;/strong&gt;: What types of reports does the tool generate?&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Specific Static Code Analysis Tools for TypeScript Codebases
&lt;/h2&gt;

&lt;p&gt;Here are three of the most popular static code analysis tools for TypeScript codebases.&lt;/p&gt;

&lt;h3&gt;
  
  
  ESLint
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://eslint.org/"&gt;ESLint&lt;/a&gt; is a popular open-source tool that checks the code for bugs, errors, and code smells before compilation. It comes with a straightforward configuration and support for TypeScript type-checking. It also allows customization, configuration rules, and plugins based on coding standards and project requirements.&lt;/p&gt;

&lt;p&gt;One noteworthy feature of ESLint is that it allows you to specify the ECMAScript version and the specific rules that are compatible with that version. Due to its flexibility, you can use ESLint as a linter for both TypeScript and JavaScript, making it an attractive choice for teams that use multiple languages with one tool.&lt;/p&gt;

&lt;p&gt;ESLint also supports frameworks like React, Vue, and Angular and integrates with popular editors like Visual Studio Code, Atom, and WebStorm.&lt;/p&gt;

&lt;h3&gt;
  
  
  TSLint
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://palantir.github.io/tslint/"&gt;TSLint&lt;/a&gt; is another popular static code analysis tool designed for TypeScript. Unlike ESLint, it is primarily intended for TypeScript codebases, making it a perfect choice for those solely dealing with TypeScript.&lt;/p&gt;

&lt;p&gt;TSLint has many rules, enabling developers to create custom rules that fit their coding standards and preferences. It also runs on every IDE with TypeScript support and can be integrated into your team's workflow through tools like Webpack and Grunt.&lt;/p&gt;

&lt;p&gt;Furthermore, TSLint is an excellent tool for using Angular, as it provides extensive support for the Angular framework and helps enforce its best practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  SonarQube
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.sonarqube.org/latest/"&gt;SonarQube&lt;/a&gt; is a dynamic code analysis tool that supports TypeScript and other programming languages. It provides an extensive set of plugins, enabling it to identify common coding issues, track technical debt, and measure code quality over time. Additionally, it provides a comprehensive dashboard that helps identify problems, making it easy to fix them quickly.&lt;/p&gt;

&lt;p&gt;A great feature of SonarQube is that it provides code coverage analysis, which helps determine the amount of code covered by tests. This allows teams to identify gaps in test coverage and prioritize areas that need more testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Effectively Introduce Static Code Analysis Tools into a TypeScript Codebase
&lt;/h2&gt;

&lt;p&gt;Introducing new tools can be challenging, but these tips can help you start effectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start Small
&lt;/h3&gt;

&lt;p&gt;Introduce the tool to your team by starting small. Run the tool on small codebases to acquaint your team with its strengths and weaknesses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customize and Configure
&lt;/h3&gt;

&lt;p&gt;Not all tools are created equal. Customize and configure the tool to meet your coding standards, project requirements, and team preferences.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automate the Process
&lt;/h3&gt;

&lt;p&gt;Automate the testing of static code analysis tools to reduce human error and inconsistency in the testing process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrate into Existing Workflows
&lt;/h3&gt;

&lt;p&gt;Effective integration into your current workflow is crucial to getting the most out of static code analysis tools. Consider integrating the tool into your IDE or command line for maximum efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Invest in Training and Education
&lt;/h3&gt;

&lt;p&gt;Training and educating team members on the tool's importance and how to interpret the reports can maximize its impact and potential.&lt;/p&gt;

&lt;h3&gt;
  
  
  Address Issues Consistently
&lt;/h3&gt;

&lt;p&gt;Consistent addressing of issues ensures the project's maintainability and increases efficiency in finding and addressing similar errors in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Regular Review and Refinement
&lt;/h3&gt;

&lt;p&gt;Regularly review and refine the configuration and adjust the tool to accommodate any changes in your workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Examples
&lt;/h2&gt;

&lt;p&gt;Here are some real-world examples of how static code analysis tools helped developers improve their TypeScript codebases:&lt;/p&gt;

&lt;h3&gt;
  
  
  Airbnb
&lt;/h3&gt;

&lt;p&gt;Airbnb is a hospitality and travel company that also provides a platform for hosts to list rental properties and for travelers to find accommodations. Their codebase is massive, with millions of lines of code in over 3000 repositories.&lt;/p&gt;

&lt;p&gt;To maintain a quality codebase, Airbnb uses ESLint and incorporates custom rules for their preferred formatting and naming conventions. ESLint helped them detect common coding issues and reduce the number of bugs in their codebase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checkmarx
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://checkmarx.com/"&gt;Checkmarx&lt;/a&gt; is a software security company providing vulnerability assessment and management services. They help identify and fix security issues early in the development cycle, reducing the cost and impact of security incidents.&lt;/p&gt;

&lt;p&gt;Checkmarx integrated TSLint into their DevOps pipeline to automate their static code analysis process. This helped them enforce coding standards, detect code smells, and identify security vulnerabilities early on.&lt;/p&gt;

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

&lt;p&gt;Static code analysis tools can be handy in a TypeScript codebase to improve code quality, consistency and save time and cost. Implementing these tools can enhance a team's productivity, and they are essential in optimizing codebase quality, maintainability, and scalability. Several static code analysis tools are available for TypeScript, and choosing the right one begins with understanding a project's unique needs and preferences. Introducing these tools into a TypeScript codebase should be done gradually, customized, configured to fit a specific project's requirements, automated, integrated, and reviewed regularly. Real-world examples from companies like Airbnb demonstrate the benefits of using these tools to maintain a quality codebase, detect common coding issues, and reduce the number of bugs in a massive codebase.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>programming</category>
      <category>engineering</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Simplifying JavaScript Development with TS-Pattern and Pattern Matching</title>
      <dc:creator>Matías Hernández Arellano</dc:creator>
      <pubDate>Wed, 26 Apr 2023 22:42:07 +0000</pubDate>
      <link>https://forem.com/matiasfha/simplifying-javascript-development-with-ts-pattern-and-pattern-matching-41pp</link>
      <guid>https://forem.com/matiasfha/simplifying-javascript-development-with-ts-pattern-and-pattern-matching-41pp</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este artículo fue originalmente escrito en &lt;a href="https://matiashernandez.dev/blog/post/simplifying-javascript-development-with-ts-pattern-and-pattern-matching"&gt;https://matiashernandez.dev&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Have you ever wished for better pattern matching in JavaScript? Look no further! We have a game changer for TypeScript developers - TS-Pattern. This powerful library simplifies pattern matching and type checking in TypeScript, allowing you to create cleaner, more readable and maintainable code. In today's post, we will explore TS-Pattern by creating a reducer function to be used with the &lt;code&gt;useReducer&lt;/code&gt; hook. But, before diving into the code, make sure to &lt;a href="https://github.com/gvergnaud/ts-pattern"&gt;check out the TS-Pattern library on GitHub&lt;/a&gt; and give the repository a star!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pattern matching&lt;/strong&gt; is a powerful feature commonly found in functional programming languages. It allows you to test a value against a set of patterns (usually defined through algebraic data types) and execute different code blocks based on the matched pattern. With this feature you can simplify the code and makes it more declarative and intuitive to read, write and maintain.&lt;/p&gt;

&lt;p&gt;Sadly JavaScript don't have this feature as part of the languge, but you can still use it through the addition of libraries such as TS-Pattern.&lt;/p&gt;

&lt;p&gt;Currently &lt;a href="https://github.com/tc39/proposal-pattern-matching"&gt;there is a proposal to add pattern matching,&lt;/a&gt; but is still in stage 1 at TC39&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vjSM7SxN9-k"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of TS-Pattern
&lt;/h2&gt;

&lt;p&gt;TS-Pattern is a library that brings pattern matching and full type safety support to your TypeScript code. The primary goal is to transform your code into a pattern-matching type of code that is fully type-safe and with type inference. Check out the &lt;a href="https://github.com/gvergnaud/ts-pattern"&gt;TS-Pattern GitHub repository&lt;/a&gt; to learn more, and make sure to give GitHub user Gabriel Vernal a follow on Twitter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with TS-Pattern
&lt;/h2&gt;

&lt;p&gt;To demonstrate how TS-Pattern works, let's create a reducer function that can be used with the &lt;code&gt;useReducer&lt;/code&gt; hook within a React component. First, let's import the necessary libraries:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can install ts-pattern directly from npm&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ts-pattern&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;Next, create a state type to hold the following (example) information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;editing&lt;/code&gt;: a boolean&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;modals&lt;/code&gt;: an object with two boolean properties, &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data&lt;/code&gt;: a &lt;code&gt;Record&amp;lt;string, unknown&amp;gt;&lt;/code&gt; type&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&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;State&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;editing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;modals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nl"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;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, define a union type for the possible action types:&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;ActionTypes&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="s1"&gt;toggleEditing&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="s1"&gt;enableEditing&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="s1"&gt;disableEditing&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="s1"&gt;toggleModelA&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="s1"&gt;toggleModelB&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="s1"&gt;updateData&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;h3&gt;
  
  
  Building Actions
&lt;/h3&gt;

&lt;p&gt;Usually, when creating the list of possible actions that can be used with the &lt;code&gt;useReducer&lt;/code&gt; hook you write a thing like this&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;Actions&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toggleEditing&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toggleModalA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you repeat that as many times as actions types you have, but it can be tedious and prone to error, so since we already have the actions as a separate union, let's use that to create an utility type to generate the actions&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;CreateAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ActionTypes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
  &lt;span class="p"&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;T&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="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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;P&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This utility type accepts a generic &lt;code&gt;T&lt;/code&gt; which extends &lt;code&gt;ActionTypes&lt;/code&gt;. If the payload (&lt;code&gt;P&lt;/code&gt;) is &lt;code&gt;undefined&lt;/code&gt; (value by default), it will return an object with only a &lt;code&gt;type&lt;/code&gt; property; otherwise, it will return an object with &lt;code&gt;type&lt;/code&gt; and &lt;code&gt;payload&lt;/code&gt; properties.&lt;/p&gt;

&lt;p&gt;Now you can use this utility type to define the different actions:&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;Actions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;CreateAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toggleEditing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;CreateAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;enableEditing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;CreateAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;disableEditing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;CreateAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toggleModelA&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="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="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;CreateAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toggleModelB&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;CreateAction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;updateData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating Reducer Function
&lt;/h3&gt;

&lt;p&gt;Time to really use ts-pattern by creating a 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="nx"&gt;reducer&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;State&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;Action&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;match&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="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;with&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toggleEditing&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="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exhaustive&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, we're using the &lt;code&gt;match&lt;/code&gt; function from TS-Pattern to match the incoming action and handle each case. The &lt;code&gt;.exhaustive()&lt;/code&gt; method ensures that every possible case is handled.&lt;/p&gt;

&lt;p&gt;The usual way to do this is by using a &lt;code&gt;switch&lt;/code&gt; statement like the following&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="nx"&gt;reducer&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;State&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;Action&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="k"&gt;switch&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="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toggleEditing&lt;/span&gt;&lt;span class="dl"&gt;'&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can you spot the bug there? &lt;br&gt;
It's easy to omit cases and Typescript doesn't give you any hint about it.&lt;/p&gt;

&lt;p&gt;Also, there is another complexity. What if you need to "switch" on two different properties?&lt;/p&gt;

&lt;p&gt;Let's say that form some actions you need perform different logic based on the payload, you may end with something like this&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="nx"&gt;reducer&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;State&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;Action&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="k"&gt;switch&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="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toggleEditing&lt;/span&gt;&lt;span class="dl"&gt;'&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="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toggleModalA&lt;/span&gt;&lt;span class="dl"&gt;'&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;action&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="c1"&gt;// perform logic A &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="k"&gt;if&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;payload&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="c1"&gt;// perform logic B&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that can become really complex to read and maintain.&lt;/p&gt;

&lt;p&gt;Let's go back to using pattern matching:&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="nx"&gt;reducer&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;State&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;Actions&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;match&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;action&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;with&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toggleEditing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;toggleEditing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;with&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;enableEditing&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="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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="kd"&gt;with&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;disableEditing&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="o"&gt;=&amp;gt;&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="kd"&gt;with&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toggleModalA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;toggleModalA&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;with&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toggleModalB&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="o"&gt;=&amp;gt;&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="kd"&gt;with&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;updateData&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="o"&gt;=&amp;gt;&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="nx"&gt;exhaustive&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;Notice that each "code branch" execute a function, this function receives as arguments all the data that was used in the &lt;code&gt;match&lt;/code&gt; method, in this case, each "callback" will receive an object like &lt;code&gt;{state: State, type: ActionTypes, payload?: SOMETHING}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That means, that we can extract the logic into a separate function, pass the corresponding arguments. As result, the logic for each code branch will be a pure function that depends only on the arguments.&lt;/p&gt;

&lt;p&gt;But, writing the types for each function arguments can be tedious, and we can do better by extracting the process into another utility type.&lt;/p&gt;

&lt;p&gt;This utility type will generate teh correct arguments based on the action type.&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;MatchEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ActionTypes&lt;/span&gt;&lt;span class="o"&gt;&amp;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;state&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="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;Extract&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Action&lt;/span&gt;&lt;span class="p"&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;T&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;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 define the action handling functions with the correct types:&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="nx"&gt;toggleEditing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MatchEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toggleEditing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toggleModelA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MatchEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toggleModelA&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using Reducer in a React Component
&lt;/h3&gt;

&lt;p&gt;Finally, use the &lt;code&gt;useReducer&lt;/code&gt; hook in a React component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;useReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Use `dispatch` to update the state based on the action types&lt;/span&gt;
  &lt;span class="nx"&gt;dispatch&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;toggleEditing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&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 that's it! You have now successfully implemented pattern matching with TS-Pattern in a React application. This technique allows for cleaner, more elegant code that is easier to read, maintain, and test. Enjoy exploring more possibilities with TS-Pattern and let us know what you think in the comments!&lt;/p&gt;

&lt;p&gt;If you have any questions or need help, you can find me on &lt;a href="https://twitter.com/matiasfha"&gt;Twitter&lt;/a&gt; or &lt;a href="https://github.com/matiasfha/ama"&gt;GitHub&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MzZgcH0l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1615457338201/5yOtr5SdF.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MzZgcH0l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1615457338201/5yOtr5SdF.jpeg" alt="Footer Social Card.jpg" width="800" height="213"&gt;&lt;/a&gt;&lt;br&gt;
✉️ &lt;a href="https://microbytes.matiashernandez.dev"&gt;Únete a Micro-bytes&lt;/a&gt;         🐦 Sígueme en &lt;a href="https://twitter.com/matiasfha"&gt;Twitter&lt;/a&gt;           ❤️ &lt;a href="https://buymeacoffee.com/matiasfha"&gt;Apoya mi trabajo&lt;/a&gt; &lt;/p&gt;

</description>
    </item>
    <item>
      <title>¿Qué es Promise.allSettled y como usarlo?</title>
      <dc:creator>Matías Hernández Arellano</dc:creator>
      <pubDate>Thu, 23 Mar 2023 13:59:06 +0000</pubDate>
      <link>https://forem.com/matiasfha/que-es-promiseallsettled-y-como-usarlo-77l</link>
      <guid>https://forem.com/matiasfha/que-es-promiseallsettled-y-como-usarlo-77l</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este artículo fue originalmente escrito en &lt;a href="https://matiashernandez.dev/blog/post/que-es-promise.allsettled-y-como-usarlo" rel="noopener noreferrer"&gt;https://matiashernandez.dev&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;En la versión ECMAScript 2021, el estándar agregó un nuevo método estático al objeto &lt;code&gt;Promise&lt;/code&gt;. Este método te permite manejar múltiples promesas de forma concurrente, pero a diferencia de &lt;code&gt;Promise.all&lt;/code&gt; este método &lt;br&gt;
espera a que todas las promesas hayan sido establecidas sin importar si estas fueron resueltas o rechazadas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;En el articulo anterior revisamos como ejeuctar Promesas de forma concurrente utilizando Promise.all, [Revisalo aqui][&lt;a href="https://matiashernandez.dev/blog/post/ejecuta-codigo-asincrono-de-forma-concurrente-en-javascript" rel="noopener noreferrer"&gt;https://matiashernandez.dev/blog/post/ejecuta-codigo-asincrono-de-forma-concurrente-en-javascript&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;Y si quieres saber mas sobre Promesas, puedes revisar este articulo introductorio: &lt;a href="https://matiashernandez.dev/blog/post/wtf-que-es-una-promesa-en-javascript" rel="noopener noreferrer"&gt;¿WTF es una promesa en JS?&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Este método es muy similar a &lt;code&gt;Promise.all&lt;/code&gt;, en efecto comparten la misma sintaxis y forma de uso, lo que cambia es el resultado que retorna.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;userId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;anotherUser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;allSettled&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt; &lt;span class="nx"&gt;promise1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;promise2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;br&gt;
&lt;strong&gt;Cabe destacar&lt;/strong&gt; que el orden del arreglo retornado corresponde con el orden de las promesas utilizadas como argumento&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Lo importante de entender es que &lt;code&gt;Promise.allSettled&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Esperará por todas las promesas sin importar su resultado &lt;/li&gt;
&lt;li&gt;El resultado de cada promesa será de la forma &lt;code&gt;{status: "fulfilled", value: &amp;lt;result&amp;gt;}&lt;/code&gt; o &lt;code&gt;{status: "rejected", reason: &amp;lt;el error&amp;gt;}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esto te permite filtrar los resultados basándose en el estado de cada promesa resuelta.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;userId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;anotherUser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;performLongOp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;anotherOp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;allSettled&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt; &lt;span class="nx"&gt;promise1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;promise2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;promise3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;promise4&lt;/span&gt; &lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fulfilled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fulfilled&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;blockquote&gt;
&lt;p&gt;Si estás usando &lt;strong&gt;Typescript&lt;/strong&gt; entonces tendrás que &lt;a href="https://matiashernandez.dev/blog/post/typescript-type-predicates-que-son" rel="noopener noreferrer"&gt;aplicar una función de predicado&lt;/a&gt; para que el filtro define el tipo correcto &lt;br&gt;
&lt;code&gt;(p): p is Extract&amp;lt;typeof p, { status: 'fulfilled' }&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ¿Cuál es la diferencia entre Promise.allSettled y Promise.all?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Promise.allSettled&lt;/code&gt; es tu opción si lo que buscas es ejecutar múltiples operaciones asíncronas de forma concurrente cuando estas no dependen entre sí y &lt;strong&gt;tampoco&lt;/strong&gt; dependen de si una u otra fue exitosa en su operación. &lt;/li&gt;
&lt;li&gt;También te será útil si lo que buscas es conocer el resultado de cada operación asíncrona.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Promise.all&lt;/code&gt; es completamente rechazado si una o más promesas utilizadas como argumentos también lo fueron. &lt;/li&gt;
&lt;/ul&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%2Fta4msusd6po9q4dahgdi.jpeg" 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%2Fta4msusd6po9q4dahgdi.jpeg" alt="Footer Social Card.jpg"&gt;&lt;/a&gt;&lt;br&gt;
✉️ &lt;a href="https://microbytes.matiashernandez.dev" rel="noopener noreferrer"&gt;Únete a Micro-bytes&lt;/a&gt;         🐦 Sígueme en &lt;a href="https://twitter.com/matiasfha" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;           ❤️ &lt;a href="https://buymeacoffee.com/matiasfha" rel="noopener noreferrer"&gt;Apoya mi trabajo&lt;/a&gt; &lt;/p&gt;

</description>
      <category>spanish</category>
    </item>
    <item>
      <title>Ejecuta código asíncrono de forma concurrente en Javascript</title>
      <dc:creator>Matías Hernández Arellano</dc:creator>
      <pubDate>Mon, 20 Mar 2023 15:33:38 +0000</pubDate>
      <link>https://forem.com/matiasfha/ejecuta-codigo-asincrono-de-forma-concurrente-en-javascript-4d91</link>
      <guid>https://forem.com/matiasfha/ejecuta-codigo-asincrono-de-forma-concurrente-en-javascript-4d91</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este artículo fue originalmente escrito en &lt;a href="https://matiashernandez.dev/blog/post/ejecuta-codigo-asincrono-de-forma-concurrente-en-javascript"&gt;https://matiashernandez.dev&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Las Promesas en Javascript son la forma standard de ejecutar código asíncrono, y son por naturaleza concurrentes.

&amp;gt; Quieres saber más sobre como trabajar con promesas? Te invito a leer esté artículo: [¿WTF es una promesa en JS?](https://matiashernandez.dev/blog/post/wtf-que-es-una-promesa-en-javascript)

Dado que una Promesa no pausa o detiene la ejecución de tu código, es sencillo llamar múltiples promesas al mismo tiempo.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;userId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;

&lt;span class="nx"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;anotherUser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Estas dos promesas se ejecutarán "al mismo" tiempo, pero, no tienes forma de controlar cuando serán resueltas, además de que, si son varias promesas ejecutadoas, el código se verá algo complejo de leer entre tanto use the &lt;code&gt;then&lt;/code&gt; y &lt;code&gt;catch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Aquí es donde muchos echan mando de &lt;code&gt;async/await&lt;/code&gt;ç&lt;/p&gt;

&lt;p&gt;A modo resumen, la sintáxis &lt;code&gt;async/await&lt;/code&gt; te permite pausar la ejecución de una promesa hasta que esta sea resuelta, creando un flujo de datos sencillo de entender.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;userId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;anotherUser&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;Ahora, tienes control sobre cuando cada promesa termina y es resuelta, y puedes utilizar las variables &lt;code&gt;result1&lt;/code&gt; y &lt;code&gt;result2&lt;/code&gt; directamente sin tener que usar un callback como en el caso anterior (dentro de &lt;code&gt;then&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Pero ahora, las promesas ya no se ejecutan en paralelo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Para saber más sobre  async/await te invito a leer este otro artículo&lt;br&gt;
&lt;a href="https://matiashernandez.dev/blog/post/entendiendo-async-y-await-en-javascript"&gt;Entendiendo async/await&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Entonces, como ejecutar promesas de forma concurrente pero mantener un flujo "sincrono"?&lt;/p&gt;

&lt;h2&gt;
  
  
  Promise.all
&lt;/h2&gt;

&lt;p&gt;El objecto Promise tiene varios métodos estáticos asociados, uno de ellos es &lt;code&gt;Promise.all&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Este método recibe como argumento un arreglo de promesas y retorna una sola que será resuelta cuando todas las otras lo hayan hecho.&lt;/p&gt;

&lt;p&gt;Como resultado, tendrás que lidear solo con una promesa y además, mantendrás la capacidad de ejecutar las promesas de forma concurrente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;userId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;anotherUser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;try&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;result1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result2&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt; &lt;span class="nx"&gt;promise1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;promise2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// Este error será el de alguna de las promesas que falló&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;Revisa la documentación &lt;a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Promise/all"&gt;de Promise.all en MDN&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;El único problema que encontrarás al utilizar &lt;code&gt;Promise.all&lt;/code&gt; es que si una de las promesas que pasaste como argumento falla, también lo hará &lt;code&gt;Promise.all&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Además, ten encuenta que &lt;code&gt;Promise.all&lt;/code&gt; tiene un comportamiento de &lt;strong&gt;fallo rápido&lt;/strong&gt;, es decir, en el momento en que una de las promesas falle, &lt;code&gt;Promise.all&lt;/code&gt; fallará y cancelara las promesas restantes.&lt;/p&gt;

&lt;p&gt;SI no te gusta utilizar &lt;code&gt;Promise.all&lt;/code&gt; por algún motivo en particular, puedes conseguir un resultado muy similar utilizando &lt;code&gt;async/await&lt;/code&gt; pero con una pequeña variación a la hora de escribir.&lt;/p&gt;

&lt;p&gt;Recuerda, el objetivo es ejecutar las promesas de forma concurrente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;userId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;anotherUser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;promise1&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;promise2&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// Este error será el de alguna de las promesas que falló&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ese código ejecutará ambas promesas antes de pausar por el resultado de cada una. El único problema es que ahora eres tu quien decide que promesa esperar primero.&lt;/p&gt;

&lt;p&gt;La ventaja de &lt;code&gt;Promise.all&lt;/code&gt; es que el tiempo de ejecución será igual al de la promesa mas lenta (en vez de sumarse como en el caso secuencial), y también que será el navegador quien se encarge de "esperar" cada promesa.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qEZ3zhVw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1615457338201/5yOtr5SdF.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qEZ3zhVw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1615457338201/5yOtr5SdF.jpeg" alt="Footer Social Card.jpg" width="880" height="235"&gt;&lt;/a&gt;&lt;br&gt;
✉️ &lt;a href="https://microbytes.matiashernandez.dev"&gt;Únete a Micro-bytes&lt;/a&gt;         🐦 Sígueme en &lt;a href="https://twitter.com/matiasfha"&gt;Twitter&lt;/a&gt;           ❤️ &lt;a href="https://buymeacoffee.com/matiasfha"&gt;Apoya mi trabajo&lt;/a&gt; &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>spanish</category>
    </item>
    <item>
      <title>¿Qué son los Type Predicates en Typescript?</title>
      <dc:creator>Matías Hernández Arellano</dc:creator>
      <pubDate>Fri, 24 Feb 2023 12:46:46 +0000</pubDate>
      <link>https://forem.com/matiasfha/que-son-los-type-predicates-en-typescript-2odn</link>
      <guid>https://forem.com/matiasfha/que-son-los-type-predicates-en-typescript-2odn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este artículo fue originalmente escrito en &lt;a href="https://matiashernandez.dev/blog/post/typescript-type-predicates-que-son"&gt;https://matiashernandez.dev&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Una pieza importante de trabajar con tipos en Typescript es el proceso conocido como el estrechamiento de tipos (type narrowing). ¿Qué es? Es el proceso de afirmar qué tipo de variable está en una parte particular del flujo de datos.&lt;/p&gt;

&lt;p&gt;En este artículo revisaremos una forma de estrechar tipos: las funciones de predicado de tipo (Type Predicates Functions).&lt;/p&gt;

&lt;p&gt;El estrechamiento de tipos nos permite tomar un tipo que es demasiado amplio y refinarlo a un tipo más específico.&lt;/p&gt;

&lt;p&gt;Este es un concepto crítico porque puede prevenir errores y hacer que nuestro código sea más expresivo y legible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comprendiendo las funciones de predicado de tipo
&lt;/h2&gt;

&lt;p&gt;Las funciones de predicado de tipo son funciones que devuelven un valor booleano y tienen una sintaxis de retorno de tipo particular. Un predicado de tipo es una aserción de tipo que verifica si un objeto tiene una propiedad específica o un conjunto de propiedades. Esto permite a TypeScript estrechar (o refinar) el tipo de un objeto basado en el resultado de la función.&lt;/p&gt;

&lt;p&gt;Aquí hay un ejemplo de una función de predicado de tipo:&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="nx"&gt;isString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&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;En este ejemplo, la función &lt;code&gt;isString&lt;/code&gt; toma un argumento &lt;code&gt;x&lt;/code&gt; de tipo &lt;code&gt;unknown&lt;/code&gt;. La función luego verifica si el typeof de &lt;code&gt;x&lt;/code&gt; es &lt;code&gt;string&lt;/code&gt;, y devuelve &lt;code&gt;true&lt;/code&gt; o &lt;code&gt;false&lt;/code&gt; en consecuencia.&lt;/p&gt;

&lt;p&gt;El tipo de retorno de la función está anotado como &lt;code&gt;x is string&lt;/code&gt;, lo que asegura que &lt;code&gt;x&lt;/code&gt; es de tipo &lt;code&gt;string&lt;/code&gt; si la función devuelve &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Luego puedes usar la función dentro de tus bloques condicionales o en cualquier otro lugar del código que necesites. El resultado de usarlo será que TypeScript reconocerá el argumento utilizado como el tipo afirmado.&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="nx"&gt;reverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="c1"&gt;// Aquí x se infiere como unknown&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;isString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Aquí x se infiere como un string &lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&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="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, la función &lt;code&gt;reverseString&lt;/code&gt; toma un argumento &lt;code&gt;x&lt;/code&gt; de tipo &lt;code&gt;unknown&lt;/code&gt;, que podría ser cualquier valor. La función luego llama a la función de predicado de tipo &lt;code&gt;isString&lt;/code&gt; para comprobar si &lt;code&gt;x&lt;/code&gt; es una &lt;code&gt;string&lt;/code&gt;.&lt;br&gt;
Si &lt;code&gt;isString(x)&lt;/code&gt; devuelve &lt;code&gt;true&lt;/code&gt;, entonces &lt;code&gt;x&lt;/code&gt; se trata como una &lt;code&gt;string&lt;/code&gt; y se puede invertir usando los métodos de string &lt;code&gt;split, reverse y join&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ventajas y desventajas
&lt;/h2&gt;

&lt;p&gt;¿Las funciones de predicado de tipo se ven bien, verdad? Pero, como todo en la vida, hay pros y contras en cada decisión que tomes.&lt;/p&gt;

&lt;p&gt;Una de las principales ventajas de las funciones de predicado de tipo es que proporcionan una forma de expresar relaciones de tipo complejas de manera legible y comprensible.&lt;br&gt;
Te permiten definir funciones personalizadas que no solo realizan una tarea específica, sino que también devuelven un valor booleano que indica a TypeScript si una variable es de un tipo particular. Esto puede hacer que tu código sea más expresivo y auto documentado.&lt;/p&gt;

&lt;p&gt;También pueden ser útiles cuando necesita realizar comprobaciones de tipo dinámicas en un objeto. Por ejemplo, imagine que tiene una función que toma un objeto como argumento, pero no está seguro de si el objeto tiene una propiedad específica. Con una función de predicado de tipo, puede verificar la presencia de esa propiedad y reducir el tipo del objeto para incluir esa propiedad.&lt;/p&gt;

&lt;p&gt;Por el lado negativo, las funciones de predicado de tipo pueden ser más difíciles de configurar y usar que los bloques condicionales. Le requieren definir funciones personalizadas y puede requerir más código para poner en marcha.&lt;/p&gt;

&lt;p&gt;Pero el problema más importante de estas funciones es un riesgo, hay una forma fácil de introducir errores en el proceso. Puede escribir predicados incorrectos que lleven a una reducción de tipo inesperada o no deseada.&lt;br&gt;
Esto puede resultar en errores en tiempo de ejecución o comportamientos inesperados, que pueden ser difíciles de diagnosticar y solucionar.&lt;/p&gt;

&lt;p&gt;Los predicados de tipo se asemejan al uso (y peligros) de usar as para las afirmaciones de tipo, puede mentir al sistema de tipos, es decir, “sé más sobre este tipo que el compilador” y forzar que el tipo sea el deseado, como ejemplo:&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="nx"&gt;isString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&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;El ejemplo anterior verifica si x es un número, y si eso es true, entonces el predicado dice que la variable es una string. Si más tarde usa ese predicado de tipo, TypeScript asume que la variable es una string y se pierde la seguridad de tipo.&lt;/p&gt;

&lt;p&gt;Mejores prácticas para usar funciones de predicado de tipo para la reducción de tipo&lt;br&gt;
Esta no es de ninguna manera una lista exhaustiva de "buenas ideas" para aplicar al trabajar con predicados de tipo, pero son una buena regla general.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defínelos cuidadosamente y asegúrese de que estén correctamente tipados.&lt;/li&gt;
&lt;li&gt;Usa nombres claros y descriptivos para las funciones de predicado de tipo.&lt;/li&gt;
&lt;li&gt;Úsalos solo cuando sean apropiados y necesarios.&lt;/li&gt;
&lt;li&gt;Considera enfoques alternativos para la reducción de tipo, como bloques condicionales o uniones discriminadas.&lt;/li&gt;
&lt;li&gt;Usa herramientas de análisis de código y pruebas automatizadas para detectar posibles errores o inconsistencias en el programa.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;En resumen, las Funciones de Predicado de Tipo son utiles para reducir tipos en TypeScript, lo que puede mejorar la legibilidad del código, la mantenibilidad y reducir errores. Sin embargo, debes tener precaución y comprender los posibles inconvenientes de su uso. Al adherirse a las prácticas y pautas recomendadas, se puede evitar comprometer la integridad del sistema de tipos y crear aplicaciones más confiables y resistentes con TypeScript. En general, las Funciones de Predicado de Tipo pueden ser una excelente adición a su caja de herramientas de TypeScript si se utilizan de manera juiciosa y responsable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qEZ3zhVw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1615457338201/5yOtr5SdF.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qEZ3zhVw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1615457338201/5yOtr5SdF.jpeg" alt="Footer Social Card.jpg" width="880" height="235"&gt;&lt;/a&gt;&lt;br&gt;
✉️ &lt;a href="https://microbytes.matiashernandez.dev"&gt;Únete a Micro-bytes&lt;/a&gt;         🐦 Sígueme en &lt;a href="https://twitter.com/matiasfha"&gt;Twitter&lt;/a&gt;           ❤️ &lt;a href="https://buymeacoffee.com/matiasfha"&gt;Apoya mi trabajo&lt;/a&gt; &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Javascript Rendering Patterns</title>
      <dc:creator>Matías Hernández Arellano</dc:creator>
      <pubDate>Mon, 13 Feb 2023 10:48:01 +0000</pubDate>
      <link>https://forem.com/matiasfha/rendering-patterns-3b89</link>
      <guid>https://forem.com/matiasfha/rendering-patterns-3b89</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este artículo fue originalmente escrito en &lt;a href="https://matiashernandez.dev/blog/post/rendering-patterns" rel="noopener noreferrer"&gt;https://matiashernandez.dev&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Web development is a constantly evolving field that is full of new and innovative solutions to tackle the ever-growing needs of modern websites. With the growth of the web, there have been numerous advances in how websites are built and rendered, giving rise to several rendering patterns and metaframeworks.&lt;/p&gt;

&lt;p&gt;In this article, we'll take a look at what rendering patterns and metaframeworks are, why there are so many of them, and explore some of the most popular options available today.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What are Rendering Patterns?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When it comes to web development, the term "rendering" refers to the process of generating and displaying content on a web page. In this context, "rendering patterns" refer to different approaches and techniques used to create and deliver web content to users.&lt;/p&gt;

&lt;p&gt;There are a variety of rendering patterns, each with its own set of benefits and trade-offs. Some patterns are geared towards static, content-driven websites, while others are designed for dynamic, interactive applications. Some patterns focus on providing a fast and efficient user experience, while others prioritize flexibility and ease of development.&lt;/p&gt;

&lt;p&gt;The choice of rendering pattern often depends on the specific needs and requirements of a project. For example, if your website is primarily static and doesn't require frequent updates, you might opt for a simple static site approach. On the other hand, if your website needs to display dynamic data, you might consider using a server-side rendering (SSR) pattern or a single-page application (SPA) pattern.&lt;/p&gt;

&lt;p&gt;Regardless of the specific pattern, the ultimate goal is to create a seamless, user-friendly experience that delivers the content your users are looking for as quickly and efficiently as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What are Metaframeworks?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Metaframeworks are a type of framework that provides a set of abstractions and tools to help developers build web applications. They can provide a number of benefits over traditional frameworks, including improved developer experience, increased productivity, and better performance.&lt;/p&gt;

&lt;p&gt;Metaframeworks differ from traditional frameworks in that they focus on providing a set of abstractions and tools that developers can use to build their applications, rather than providing a complete and prescriptive solution. This allows developers to have more control over the architecture and structure of their applications, and to tailor their solutions to the specific needs of their projects.&lt;/p&gt;

&lt;p&gt;In web development, metaframeworks often provide abstractions for server-side rendering, client-side rendering, and data management, as well as tools for managing the build process, optimizing performance, and handling deployment. Some popular metaframeworks include Next.js, Gatsby, Nuxt, and SvelteKit.&lt;/p&gt;

&lt;p&gt;The use of metaframeworks can help to simplify the development process and improve the overall performance and scalability of web applications. They can also help to make it easier for teams of developers to work together on a project, as they provide a common set of tools and abstractions that everyone can use.&lt;/p&gt;

&lt;p&gt;Ultimately, metaframeworks are an important tool for modern web development, and can help to make it easier and faster to build high-quality, scalable web applications. Whether you are a solo developer or part of a large team, metaframeworks can help you to build better web applications more quickly and with greater ease.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why are there so many Rendering Patterns?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The proliferation of rendering patterns in web development can be attributed to the constant evolution of technology and the diverse needs of businesses and developers. With the advent of new and improved technologies, developers are presented with a multitude of options for building websites and web applications. Each technology has its own unique set of strengths and weaknesses, and it is up to the developer to choose the best tool for the job at hand.&lt;/p&gt;

&lt;p&gt;Moreover, different businesses have different requirements for their websites and web applications, and a single technology or solution may not meet the needs of every business. As a result, developers are constantly searching for new and innovative solutions that can provide the best results for their clients. This drives the creation of new rendering patterns and the improvement of existing ones, as developers strive to find the most efficient and effective ways to build web applications.&lt;/p&gt;

&lt;p&gt;In addition, the open-source nature of web development has enabled developers to freely share their solutions and innovations with the community. This sharing of knowledge and expertise has accelerated the development of new rendering patterns, as developers learn from each other and build upon existing solutions to create even better ones.&lt;/p&gt;

&lt;p&gt;It is also important to note that the wide availability of web development tools and libraries has made it easier for developers to experiment with new approaches and technologies. This has encouraged developers to push the boundaries of what is possible with web development and has led to the creation of new rendering patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Rendering Patterns Overview&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here's an overview of some of the most popular rendering patterns:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Static Site&lt;/strong&gt;: The OG of web development, when things were simple, you could just upload a bunch of static files to a service through FTP. This is still a popular option today, and there are several frameworks, such as Hugo, Jekyll, and A11y, that make it easy to create a static site. However, it's also possible to build a static site "by hand" without the use of any framework.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MPA (Multi-Page Application)&lt;/strong&gt;: This pattern emerged as a solution to the dynamic data problem faced by static sites. MPA uses server-side code to generate HTML based on dynamic data. This is how many senior developers first got started with servers and databases, and popular frameworks include Laravel, Rails, and Django.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SPA (Single-Page Application)&lt;/strong&gt;: This is the golden era of the main JavaScript frameworks and addresses the navigation issue faced by MPA. SPA ships a large amount of JavaScript to render all aspects of the application, but it also has its own set of problems, such as poor SEO, too much JavaScript, and loading spinner issues. Popular SPA frameworks include Angular, React, Vue, Svelte, and Solid.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSR (Server-Side Rendering)&lt;/strong&gt;: This pattern involves initial rendering being done on the server (usually with Node or another engine), after which client-side JavaScript takes over to provide the SPA experience. Popular SSR frameworks include Next.js, Nuxt, and SvelteKit. However, this pattern requires a server.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SSG&lt;/strong&gt; (&lt;strong&gt;Static Site Generation)&lt;/strong&gt;: This pattern, known as SSG, is similar to the first one but allows for a better developer experience by using a web framework, dynamic data, etc. The framework will "compile" the site into multiple static pages. Gatsby is the king in this area, but other frameworks like Next.js, Nuxt, and SvelteKit can also implement this pattern.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ISR (Incremental Static Regeneration)&lt;/strong&gt;: ISR is a newer approach that tries to solve some of the problems with SSG. With ISR, you can deploy a static site and then rebuild individual pieces of it "on the fly" using cache. This way, you can enjoy the benefits of a static site while also allowing for some dynamic content.&lt;/p&gt;

&lt;p&gt;Vercel is a platform that supports ISR out-of-the-box. This makes it a great option for developers who want to implement ISR without having to set up and manage a server themselves.&lt;/p&gt;

&lt;p&gt;The main advantage of ISR is that it solves the problem of long build and deployment times that comes with SSG. With ISR, you can deploy a static site and then rebuild individual pieces as needed, which greatly reduces the time it takes to deploy changes.&lt;/p&gt;

&lt;p&gt;However, it's worth noting that ISR still requires a server to function, which can be a drawback for some users.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Partial Hydration&lt;/strong&gt; is a rendering pattern that aims to solve the problem of the first load being "not usable" in Hydration patterns. With Partial Hydration, the server renders the HTML and ships it to the browser, but only the required JavaScript is lazy loaded, making the hydrated page interactive by pieces.&lt;/p&gt;

&lt;p&gt;This approach can greatly improve the user experience, as it allows the user to start interacting with the site while the rest of the JavaScript is still being loaded.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Islands Architecture&lt;/strong&gt; is an approach that was first popularized by &lt;a href="https://twitter.com/ksylor" rel="noopener noreferrer"&gt;@ksylor&lt;/a&gt; and is now being (re)popularized by &lt;a href="https://twitter.com/astrodotbuild" rel="noopener noreferrer"&gt;@astrodotbuild&lt;/a&gt;. The idea behind Islands Architecture is to prevent JavaScript from taking over the entire page and instead isolate the pieces that require it.&lt;/p&gt;

&lt;p&gt;With this approach, you start with static HTML and use JavaScript to hydrate isolated components. This allows you to keep using the "view layer" of your choice, whether that's React, Svelte, or Solid, and write your application as you normally would. The result is a static site with pieces of interactivity, or "islands."&lt;/p&gt;

&lt;p&gt;One of the benefits of Islands Architecture is that it can improve the overall performance of the site, as only the necessary JavaScript is loaded.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Resumability&lt;/strong&gt; is a relatively new rendering pattern that is gaining popularity among developers. It was popularized by  &lt;a href="https://twitter.com/QwikDev" rel="noopener noreferrer"&gt;@QwikDev&lt;/a&gt; and coined by &lt;a href="https://twitter.com/mhevery" rel="noopener noreferrer"&gt;@mhevery&lt;/a&gt;. The idea behind Resumability is to avoid Hydration altogether by rendering on the server and sharing both the static files and the framework state.&lt;/p&gt;

&lt;p&gt;In this way, the application does not "start over" when it is loaded, but instead "continues where it left off" on the server. The best analogy for this is a virtual machine that can be paused, moved to another place, and then continue exactly where it was left.&lt;/p&gt;

&lt;p&gt;Resumability has the potential to greatly improve the user experience, as it allows for a smoother, more seamless transition from server to client. However, it's worth noting that this approach is still relatively new, so there may be some challenges to overcome as the technology continues to evolve.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;With so many rendering patterns and metaframeworks available, it can be overwhelming to choose the right one for your project. It's important to consider your specific use case and requirements before making a decision, as each rendering pattern and metaframework has its own pros and cons. Ultimately, the best choice will depend on your specific needs and goals.&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%2Fta4msusd6po9q4dahgdi.jpeg" 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%2Fta4msusd6po9q4dahgdi.jpeg" alt="Footer Social Card.jpg" width="800" height="213"&gt;&lt;/a&gt;&lt;br&gt;
✉️ &lt;a href="https://microbytes.matiashernandez.dev" rel="noopener noreferrer"&gt;Únete a Micro-bytes&lt;/a&gt;         🐦 Sígueme en &lt;a href="https://twitter.com/matiasfha" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;           ❤️ &lt;a href="https://buymeacoffee.com/matiasfha" rel="noopener noreferrer"&gt;Apoya mi trabajo&lt;/a&gt; &lt;/p&gt;

</description>
      <category>gemini</category>
      <category>cli</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Deep Cloning in JavaScript: The Modern Way. Use structuredClone</title>
      <dc:creator>Matías Hernández Arellano</dc:creator>
      <pubDate>Thu, 26 Jan 2023 13:39:20 +0000</pubDate>
      <link>https://forem.com/matiasfha/deep-cloning-in-javascript-the-modern-way-use-structuredclone-1nej</link>
      <guid>https://forem.com/matiasfha/deep-cloning-in-javascript-the-modern-way-use-structuredclone-1nej</guid>
      <description>&lt;p&gt;A few days ago, I learned that Javascript has a native way of creating deep copies of an object.&lt;/p&gt;

&lt;p&gt;This article will explore the native method for deep cloning an object in JavaScript. We will also discuss the difference between shallow and deep copying in JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a deep copy or clone?
&lt;/h2&gt;

&lt;p&gt;Javascript objects are usually stored in memory and can only be copied by reference, meaning, that a variable does not store an object in itself, but rather an identifier that represents the memory location of the object. Therefore, objects cannot be copied in the same way as primitives.&lt;/p&gt;

&lt;p&gt;There are two types of copy within the Javascript world: shallow and deep.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shallow Copies
&lt;/h3&gt;

&lt;p&gt;A shallow copy is a copy of an object that only copies the reference to the object, not the actual data. If the original object is modified, the copy will also be modified.&lt;/p&gt;

&lt;p&gt;For example, let's say we have an object called "originalObject" that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;originalObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;street&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123 Main St&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Anytown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Anystate&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;If we create a shallow copy of this object using the &lt;code&gt;Object.assign()&lt;/code&gt; method, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shallowCopy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="nx"&gt;originalObject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;shallowCopy&lt;/code&gt; object will look exactly the same as the &lt;code&gt;originalObject&lt;/code&gt;. However, if we modify the &lt;code&gt;address&lt;/code&gt; property of the &lt;code&gt;originalObject&lt;/code&gt;, the &lt;code&gt;address&lt;/code&gt; property of the &lt;code&gt;shallowCopy&lt;/code&gt; will also be modified because both objects are pointing to the same address object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;originalObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NewCity&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shallowCopy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//Output: "NewCity"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deep copies
&lt;/h3&gt;

&lt;p&gt;On the other hand, A deep copy creates a new object with its own set of data, separate from the original object. If the original object is modified, the copy will not be affected.&lt;/p&gt;

&lt;p&gt;For example, let's say we have an object called "originalObject" that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;originalObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;street&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123 Main St&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Anytown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Anystate&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;To create a deep copy of this object, we can use the &lt;code&gt;JSON.parse(JSON.stringify(obj))&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;deepCopy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;originalObject&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we now modify the &lt;code&gt;address&lt;/code&gt; property of the &lt;code&gt;originalObject&lt;/code&gt;, the &lt;code&gt;address&lt;/code&gt; property of the &lt;code&gt;deepCopy&lt;/code&gt; will not be modified because they are completely different objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;originalObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NewCity&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deepCopy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//Output: "Anytown"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Please note that JSON.parse(JSON.stringify(obj)) method is not suitable for complex objects with circular references. In this case, you can use a library such as lodash, underscore or a specific deep copy function.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Native deep cloning: &lt;code&gt;structuredClone&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;As shown in the previous example, Javascript has ways to work around the deep copy problem. In the example, it uses the serialization strategy. Basically, it transforms an object into a JSON representation and then parses it again.&lt;/p&gt;

&lt;p&gt;But, now the Web API has a new way of solving the deep cloning issue by using the &lt;code&gt;structuredClone&lt;/code&gt; global method.&lt;/p&gt;

&lt;p&gt;This method was recently added to expose the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm"&gt;structured clone algorithm&lt;/a&gt;, a way to create deep copies of Javascript values that can be used, for example, to transfer JS values from or to a WebWorker.&lt;/p&gt;

&lt;p&gt;This algorithm has been part of the HTML spec for a long time but only as a tool used by other APIs. Before &lt;code&gt;structuredClone&lt;/code&gt; was added, you have to do some workarounds to use it, like using &lt;code&gt;postMessage&lt;/code&gt; to send messages to “ourselves”.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="%5Bhttps://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal%5D(https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal)"&gt;Structured Cloning&lt;/a&gt; is an algorithm created and used to transfer values from one real into another, like the &lt;code&gt;postMessage&lt;/code&gt; call that send a message to another window or Webworker.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a global method that handles the creation of deep copies of any given value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deepCopy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;structuredClone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;originalObject&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 review a quick example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;site&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://matiashernandez.dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;published&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;sociales&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twitter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://twitter.com/matiasfha&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;youtube&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://dub.sh/channel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;//Subscribe!&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="nx"&gt;copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;structuredClone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is all it takes to create a full/deep copy of the original object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;Even tho the structured cloning algorithm address many of the issues with &lt;code&gt;JSON.stringify&lt;/code&gt; it still has some limitations that you need to be aware of.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Can’t clone Function objects: If the object you want to clone contains functions, they will be discarded and a &lt;code&gt;DataCloneError&lt;/code&gt; will be thrown.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can’t clone DOM nodes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Can’t clone some properties like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;lastIndex&lt;/code&gt; from a &lt;code&gt;Regexp&lt;/code&gt; object&lt;/li&gt;
&lt;li&gt;setters, getters, and similar metadata&lt;/li&gt;
&lt;li&gt;the prototype chain will not be duplicated&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Alternatives
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;structuredClone&lt;/code&gt; is relatively, but the need for deep cloning values has been there forever. So let’s check some alternatives to the &lt;code&gt;structuredClone&lt;/code&gt; method that the web development community has been using&lt;/p&gt;

&lt;h3&gt;
  
  
  Object.assign and spread syntax.
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Object.assign&lt;/code&gt; has been the way to create copies for a long time, but here we are talking about deep copy, but &lt;code&gt;Object.assign&lt;/code&gt; can only provide shallow copy, and &lt;strong&gt;is not able to copy nested objects or arrays&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The spread syntax was added on ES2018 to the properties of objects to provide a convenient way to perform shallow copies, is the equivalent of &lt;code&gt;Object.assign&lt;/code&gt; so you can treat them as equals.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;site&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://matiashernandez.dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;published&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;socials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twitter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://twitter.com/matiasfha&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;youtube&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://dub.sh/channel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;//Subscribe!&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="nx"&gt;copy1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;copy2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Error, this will update the publishedDate property of the original object&lt;/span&gt;
&lt;span class="nx"&gt;copy1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;published&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

&lt;span class="c1"&gt;// Error, this will add an empty object to the original object&lt;/span&gt;
&lt;span class="nx"&gt;copy2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;socials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  JSON.parse and JSON.stringify
&lt;/h3&gt;

&lt;p&gt;This has been the trick to get a copy that includes nested objects and arrays; it has a really good performance but is still doesn’t entirely solve the problem of the deep copy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;site&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://matiashernandez.dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;published&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;socials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twitter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://twitter.com/matiasfha&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;youtube&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://dub.sh/channel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;//Subscribe!&lt;/span&gt;
    &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// The publishedDate property is now a string&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The strategy here is first to transform the object into a string using &lt;code&gt;JSON.stringify&lt;/code&gt; this method will serialize each property of the object recursively so, all the nested properties will also be serialized.&lt;/p&gt;

&lt;p&gt;Then it uses &lt;code&gt;JSON.parse&lt;/code&gt; to “un-serialize” the serialized object and generate a new object from the source.&lt;/p&gt;

&lt;p&gt;The problem with this strategy is the serialization process. Every object in Javascript has a property method named &lt;code&gt;toString&lt;/code&gt; that implements a way to transform the object into a string representation of itself. Is this implementation the one used by &lt;code&gt;JSON.stringify&lt;/code&gt; to serialize each property, the problem comes with properties like the &lt;code&gt;Date&lt;/code&gt; object used in the &lt;code&gt;original&lt;/code&gt; object, it’s serialized to a string, and a string cannot be transformed back to &lt;code&gt;Date&lt;/code&gt; by &lt;code&gt;JSON.parse&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;JSON.stringify&lt;/code&gt; can only handle basic objects, arrays, and primitives. Other types can be handled in unpredictable ways. For example, Dates are converted to strings, while Sets are simply converted to &lt;code&gt;{}&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  lodash.cloneDeep
&lt;/h3&gt;

&lt;p&gt;This has been the “defacto” way of getting a deep copy, but it means you need to add a dependency just to be able to perform a deep copy.&lt;/p&gt;

&lt;p&gt;If you import the function, it will cost you &lt;code&gt;5.3K&lt;/code&gt; gzipped, or if you add the entire library, it will be &lt;code&gt;25k&lt;/code&gt; gzipped. That’s a lot if you only want to be able to create deep clones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Browser Support
&lt;/h2&gt;

&lt;p&gt;The best part of using &lt;code&gt;structuredClone&lt;/code&gt; is not only that it has good performance and achieves the task in a good way, but is supported in all major browsers and engines.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lv2Is8v3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/avy4pkoa4fhtkr8pkw24.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lv2Is8v3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/avy4pkoa4fhtkr8pkw24.png" alt="Image description" width="880" height="229"&gt;&lt;/a&gt;&lt;br&gt;
Check &lt;a href="https://caniuse.com/?search=structuredClone"&gt;the canIUse site&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;If you need to create deep clones of any value in Javascript, reach for the &lt;code&gt;structuredClone&lt;/code&gt; method and “Use the Platform”. It is time to ditch the old habits of using workarounds and embrace a better JS ecosystem.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Should You Learn Typescript? What Parts Should You Learn?</title>
      <dc:creator>Matías Hernández Arellano</dc:creator>
      <pubDate>Sun, 22 Jan 2023 02:13:54 +0000</pubDate>
      <link>https://forem.com/matiasfha/should-you-learn-typescript-what-parts-should-you-learn-433e</link>
      <guid>https://forem.com/matiasfha/should-you-learn-typescript-what-parts-should-you-learn-433e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este artículo fue originalmente escrito en &lt;a href="https://matiashernandez.dev/blog/post/should-you-learn-typescript-what-parts-should-you-learn"&gt;https://matiashernandez.dev&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Learning Typescript can be daunting at first. So why should you know it? Or even better, how should you learn it?. &lt;/p&gt;

&lt;p&gt;As a web developer, you know that Typescript is growing in popularity and usage, but the web development landscape is already complex. You may be wondering why to add more complexity to the mix.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ocXWLQbr-mE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;You may find Typescript content with incredible feats, bending the type system to build complex solutions to some problems, and you may wonder: do I need to learn all of this? Nowadays, types have become a two-headed monsters. You have the type-level programming algorithms with all of that complexities, but also you have the everyday Javascript with superpowers, annotations, and some utilities from the language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Back to fundamentals
&lt;/h2&gt;

&lt;p&gt;Let's remember why Typescript was invented. It was created 10 or 11 years ago. Some, something like that. But with the only purpose of improving the developer experience. At that time, the DX was awful and Typescript, adding static analysis and type safety to the mix, was able to improve that process.&lt;/p&gt;

&lt;p&gt;Offering good developer experience, like a suitable auto-complete good documentation, go to definition, rename and refactoring, and catching bugs earlier, creating a more streamlined. Because that bugs will never reach the user. &lt;br&gt;
So we have this two-layer language, the "every day" or not type-level programming and the type-level algorithms.&lt;/p&gt;

&lt;p&gt;You'll find pattern-matching type conditionals, recursion map types, and more at the type level. &lt;br&gt;
And in the everyday task script, you'll find type rotations and maybe some type utilities like &lt;code&gt;Pick&lt;/code&gt;, &lt;code&gt;Omit&lt;/code&gt;, &lt;code&gt;Exclude&lt;/code&gt;, &lt;code&gt;keyof&lt;/code&gt;, &lt;code&gt;extends&lt;/code&gt;, etcetera. &lt;/p&gt;

&lt;p&gt;It's at this level where the real power of Typescript resides because that is the thing you might need.&lt;/p&gt;

&lt;p&gt;Typescript should be out of your way to help and allow you to create your incredible application. The library authors, on the other hand, are the ones that need to worry about the obscure features of Typescript because they need to build a flexible and robust product that can support all of the use cases.&lt;/p&gt;

&lt;p&gt;Offering the tools required to allow Typescript to give you reasonable type inference. So you write functions with a few types of annotations and are done. You have all of the benefits you want.&lt;/p&gt;

&lt;p&gt;So, let me be honest: I enjoy challenging myself and writing type-level algorithms or solutions. But in my regular job or even some of my side projects, I have yet to encounter the need to note complex solutions. &lt;/p&gt;

&lt;p&gt;An example of &lt;a href="https://youtu.be/yQyQa0gbqU0"&gt;that complexity is the query string parser&lt;/a&gt;  that I have in a few videos that you can find &lt;a href="https://youtu.be/QryUZJ0Tx90"&gt;in my Youtube Channel&lt;/a&gt;. That allows you to parse the query string and generate the object type you need to ensure that the thing in the query string is something you need.&lt;/p&gt;

&lt;p&gt;But most of the time, you'll not write that because you'll use some router library like &lt;a href="https://reactrouter.com/"&gt;React Router&lt;/a&gt; or &lt;a href="https://tanstack.com/router"&gt;Tanstack Router&lt;/a&gt; and are those libraries, the ones that implement something like that example in a better way. To offer you the solutions, you need to pass the query string.&lt;/p&gt;

&lt;p&gt;So you should not be worried about all of that.&lt;/p&gt;

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

&lt;p&gt;In conclusion, TypeScript can be complex at first, but you should focus on the parts that really matter, the parts that will most impact your web development process, starting with type script in your everyday projects.&lt;/p&gt;

&lt;p&gt;Start by annotating, adding some good type utilities, and choosing good libraries with reasonable type inference and type safety if you think it's fun to challenge yourself with type level. Go all in. It will be fun, and you will learn a lot. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is a blog post based on a video on &lt;a href="https://youtube.com/@matiasfha?sub_confirmation=1"&gt;my youtube channel&lt;/a&gt;. If you like the content &lt;a href="https://youtube.com/@matiasfha?sub_confirmation=1"&gt;please subscribe&lt;/a&gt; to find out more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qEZ3zhVw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1615457338201/5yOtr5SdF.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qEZ3zhVw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1615457338201/5yOtr5SdF.jpeg" alt="Footer Social Card.jpg" width="880" height="235"&gt;&lt;/a&gt;&lt;br&gt;
✉️ &lt;a href="https://microbytes.matiashernandez.dev"&gt;Únete a Micro-bytes&lt;/a&gt;         🐦 Sígueme en &lt;a href="https://twitter.com/matiasfha"&gt;Twitter&lt;/a&gt;           ❤️ &lt;a href="https://buymeacoffee.com/matiasfha"&gt;Apoya mi trabajo&lt;/a&gt; &lt;/p&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to integrate TailwindCSS with SvelteKit</title>
      <dc:creator>Matías Hernández Arellano</dc:creator>
      <pubDate>Mon, 16 Jan 2023 19:42:18 +0000</pubDate>
      <link>https://forem.com/matiasfha/how-to-integrate-tailwindcss-with-sveltekit-48md</link>
      <guid>https://forem.com/matiasfha/how-to-integrate-tailwindcss-with-sveltekit-48md</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este artículo fue originalmente escrito en &lt;a href="https://matiashernandez.dev/blog/post/how-to-integrate-tailwindcss-with-sveltekit" rel="noopener noreferrer"&gt;https://matiashernandez.dev&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are two types of people in the dev world. The ones that love tailwind and the ones that hate it.&lt;/p&gt;

&lt;p&gt;If you are in the first group, then you probably want to use Tailwind in most of your projects because of the benefits you find in it.&lt;/p&gt;

&lt;p&gt;I’m using Tailwind on my site and for most of my side projects and demos. But, sometimes, adding TailwindCSS to your projects can be annoying or confusing. In this article, you’ll find how to integrate TailwindCSS with SvelteKit.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This article focus on one approach, if you want to check a different path to accomplish the same I recommend you to check &lt;a href="https://enbonnet.hashnode.dev/how-to-configure-tailwindcss-on-sveltekit-10" rel="noopener noreferrer"&gt;this article by Ender Bonnet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, a bit of background.&lt;/p&gt;

&lt;p&gt;SvelteKit, is the meta-framework that uses Svelte to handle the UI rendering processes (kind of Nextjs for React). It provides different features and functionalities that help you to develop full-stack applications, like router, SSR, build optimizations, CSR, and more. Check &lt;a href="https://kit.svelte.dev/docs/introduction" rel="noopener noreferrer"&gt;the official documentation&lt;/a&gt; to read more about it.&lt;/p&gt;

&lt;p&gt;On the other hand for this integration, there is &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;TailwindCSS&lt;/a&gt;, and unless you’re living under a rock, you should at least listen about it. TailwindCSS and is an utilitiy-first CSS framework that offers a pack full of classes that can be composed to create any design. It is like writing CSS without writing CSS.&lt;/p&gt;

&lt;p&gt;Now, to the core of this content.&lt;/p&gt;

&lt;p&gt;For this tutorial, I’ll show you how to use a &lt;a href="https://github.com/svelte-add/svelte-add" rel="noopener noreferrer"&gt;utility package named svelte-add&lt;/a&gt; to handle the integrations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrate TailwindCSS into a pre-existing SvelteKit project
&lt;/h3&gt;

&lt;p&gt;One way to add TailwindCSS is to integrate it into a project you already have. Let’s assume that you already have a SvelteKit project and know how to use the terminal.&lt;/p&gt;

&lt;p&gt;The only thing you need is to run these two commands&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx svelte-add@latest tailwindcss pnpm install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And you’re done.&lt;/p&gt;

&lt;p&gt;The first command (the one that calls &lt;code&gt;npm&lt;/code&gt; or &lt;code&gt;pnpmx&lt;/code&gt; ) is the one in charge of setting things, creating configuration files, and updating your configurations to use Tailwind (which is a postcss plugin).&lt;/p&gt;

&lt;p&gt;The last one, is to update your dependencies (use the package manager of your choice here).&lt;/p&gt;

&lt;p&gt;After that, you’re ready to go and use TailwindCSS in your &lt;code&gt;.svelte&lt;/code&gt; files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrate TailwindCSS into a new SvelteKit project
&lt;/h3&gt;

&lt;p&gt;The other way of getting this integration done is by creating a project from scratch - In fact, this is the preferred method - What you need here is to execute a different command than the one that the official documentation mention.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm create @svelte-add/kit@latest my-awesome-app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That will show you a prompt to select any integration you have&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;svelte-add&lt;/code&gt; support several integrations like: Bulma, Coffeescript, TailwindCSS, MDsveX, SCSS, etc&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For this tutorial, pick TailwindCSS or directly define that in the command line like&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm create @svelte-add/kit@latest my-awesome-app -- --with tailwindcss&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That will generate the skeleton SvelteKit application with Tailwind ready to be used. You now need to install dependencies and move on to building your incredible application.&lt;/p&gt;

&lt;p&gt;And that’s a wrap, using &lt;code&gt;svelte-add&lt;/code&gt; is an easy way to integrate 3rd party libraries/configurations into your SvelteKit project.&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%2Fta4msusd6po9q4dahgdi.jpeg" 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%2Fta4msusd6po9q4dahgdi.jpeg" alt="Footer Social Card.jpg" width="800" height="213"&gt;&lt;/a&gt;&lt;br&gt;
✉️ &lt;a href="https://microbytes.matiashernandez.dev" rel="noopener noreferrer"&gt;Únete a Micro-bytes&lt;/a&gt;         🐦 Sígueme en &lt;a href="https://twitter.com/matiasfha" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;           ❤️ &lt;a href="https://buymeacoffee.com/matiasfha" rel="noopener noreferrer"&gt;Apoya mi trabajo&lt;/a&gt; &lt;/p&gt;

</description>
      <category>devops</category>
      <category>discuss</category>
      <category>learning</category>
      <category>community</category>
    </item>
  </channel>
</rss>
