<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Joseph Barron</title>
    <description>The latest articles on DEV Community by Joseph Barron (@jdbar).</description>
    <link>https://dev.to/jdbar</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%2F448517%2Fa6266e2e-b1bb-48fc-8e36-2a7aca277e5e.jpg</url>
      <title>DEV Community: Joseph Barron</title>
      <link>https://dev.to/jdbar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jdbar"/>
    <language>en</language>
    <item>
      <title>How Software Development is Changing Forever, and How You'll Need to Change With It</title>
      <dc:creator>Joseph Barron</dc:creator>
      <pubDate>Wed, 08 Jan 2025 08:53:46 +0000</pubDate>
      <link>https://dev.to/jdbar/how-software-development-is-changing-forever-and-how-youll-need-to-change-with-it-1jih</link>
      <guid>https://dev.to/jdbar/how-software-development-is-changing-forever-and-how-youll-need-to-change-with-it-1jih</guid>
      <description>&lt;p&gt;I'm sorry, you'll probably find this is a really long article. From the title, you probably think I'm either about to about to profess the infinite glory of AI — or proclaim how it will gradually end the world and take &lt;em&gt;your&lt;/em&gt; job.&lt;/p&gt;

&lt;p&gt;But I promise that's not what this is. In fact, since you're reading this here on Dev.to, I promise to tell you why you're likely to do well in a post-AI world.&lt;/p&gt;




&lt;p&gt;For as long as programming has existed, one thing has remained constant: it’s always been about writing code. Despite how computing has changed over decades, one thing has remained the same... we write code, and the machine follows our instructions.&lt;/p&gt;

&lt;p&gt;Today, tools like Copilot, Cursor, and ChatGPT are turning that process on its head. AI doesn’t just follow instructions; it helps create them. You describe what you need, and it spits out code that gets you halfway there—sometimes further.&lt;/p&gt;

&lt;p&gt;It feels unbelievable.&lt;/p&gt;

&lt;p&gt;But it raises unsettling questions. If AI gets better at writing code, what’s left for developers? Is this the end of a decades-old career—or the beginning of something far greater?&lt;/p&gt;

&lt;p&gt;The best programmers I know are not intimidated by the hallucination-riddled outputs of ChatGPT and Claude. But the history of computing suggests that these programmers shouldn't be so confident that the world won't demand that they adapt anyways.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Next Big Abstraction in Computing
&lt;/h2&gt;

&lt;p&gt;Each shift in the evolution of how we produce software has been a story of abstraction. The amount of data needed to build an application has not decreased over time, it's gotten larger. But the words we use to describe that data have become more expressive and succinct.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Assembly Language:&lt;/strong&gt; No more punch card systems or painstakingly producing machine code by hand. With assembly, developers could write instructions using a more human-readable syntax, abstracting away the binary intricacies of hardware. This meant they could shift focus from managing individual bytes to designing and building more complex systems—operating systems, rudimentary user interfaces, and early software applications. It was a big first step toward programming as we know it today: enabling humans to communicate with machines without needing to speak like one.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compiled Languages:&lt;/strong&gt; Portable, high-level code revolutionized programming. Instead of writing instructions specific to a machine’s hardware, developers could write code in high-level languages like FORTRAN or C, which compilers translated into optimized machine code. This abstraction allowed developers to focus on solving complex problems rather than worrying about hardware-specific details. The result? The rise of portable, scalable applications—from enterprise systems to the software that powers our everyday lives. It wasn’t just about making programming easier; it was about opening the door to larger, more ambitious projects that transformed industries.&lt;br&gt;
​&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interpreted Languages:&lt;/strong&gt; Languages like Python and JavaScript took abstraction a step further, prioritizing ease of use, flexibility, and platform independence. With interpreted languages, developers didn’t need to compile code into machine instructions—they could write and run programs dynamically, often with instant feedback. This democratized programming, making it accessible to people who didn’t have traditional technical backgrounds. Despite being notorious for quirks and inefficiencies, these languages fueled the web and app revolutions, enabling entire ecosystems of innovation. Today, countless communities thrive around building micro-SaaS apps, games, and experimental projects that wouldn’t have been possible without these accessible tools.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If history has taught us anything, it’s that new tools don’t eliminate jobs—they create them. &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%2Fc7losw5f90xscbt30th3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7losw5f90xscbt30th3.png" alt="A guy in 1957: " width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A guy in 1957: "A compiler could never outperform my hand-crafted machine code."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Programming originally meant managing every detail—manually allocating memory, writing low-level code tailored to specific hardware, and understanding every intricacy of the machine. A skillset that was incredibly niche and difficult to acquire. Today's students can effortlessly render their React pièce de résistance in any environment that can run a browser, without worrying about the nitty gritty details. Each leap in abstraction has not only made programming complex systems easier but has also unlocked countless new opportunities, expanding what’s possible with far less effort.&lt;/p&gt;

&lt;p&gt;I believe AI-assisted coding fits neatly into this ongoing story of abstractions. Each transition in the evolution of programming has shared a central theme: that code can be represented as data. Every paradigm shift has been about abstracting how we describe and manipulate that data. Large language models take this abstraction one step further: they allow us to represent code (and anything else generative AI can produce) in the form of natural language.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Natural Language:&lt;/strong&gt; Generative LLMs have unlocked a form of software development that was previously relegated to &lt;a href="https://en.wikipedia.org/wiki/Inform#Example_game_2" rel="noopener noreferrer"&gt;niche artisan programming languages&lt;/a&gt;: the ability to build applications using plain English. Well, almost. While these models can “autocomplete” their way to appearing technically proficient, achieving reliable and precise outputs still requires significant technical expertise. However, their advancing capabilities give us a preview of an inevitable future where natural language programming is the de-facto way to produce software.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Changes for Developers?
&lt;/h2&gt;

&lt;p&gt;Unlike many of the previous paradigm shifts in computing, AI is not just abstracting code... it is also abstracting effort itself. A strong developer can describe in detail what they need, and an AI can nearly handle the rest. "Agentic" tools are becoming capable of brainstorming and planning somewhat autonomously—at least, they give the appearance of doing so. The code these programs write won't necessarily pass the sniff test of the top programmers (in fact, the code might not even run), but it doesn't seem like we're far away from getting consistent and reliable outputs.&lt;/p&gt;

&lt;p&gt;AI also isn’t a deterministic tool in the toolbox, like a compiler. There's a degree of chaos and unpredictably that, when combined with its &lt;a href="https://www.youtube.com/watch?v=Pec5SDvgOrQ" rel="noopener noreferrer"&gt;approximate knowledge of many things&lt;/a&gt;, enables it to act as a pretty good collaborator. Even if you don't use the code it writes directly, you might find it's a wonderful &lt;a href="https://en.wikipedia.org/wiki/Rubber_duck_debugging" rel="noopener noreferrer"&gt;rubber-duck&lt;/a&gt;, capable of bouncing ideas back and forth, willing to iterate on any ridiculous thought you have. Its ability to parse large amounts of documentation quickly is useful when researching how to go about building a system. And that means the role of the developer will evolve in a new way.&lt;/p&gt;

&lt;p&gt;In the future, the developers with the highest job security won’t necessarily be the ones most deeply familiar with language features, APIs, and libraries. AI—even in its current impressive-but-primitive state—can already approximate much of that information with surprising accuracy.&lt;/p&gt;

&lt;p&gt;Instead, the developers who stand to gain the most will be those who excel at the things AI will (hopefully) struggle with for a long time. AI, at least as of today, cannot hold an entire business context in its memory. It doesn’t understand the domain. It doesn’t grasp the customer, the roadmap, the budget, the politics, the culture, the positioning, the strategy—or the team’s past failures and victories. It doesn’t exist in the world, building relationships with the people navigating the ship it’s been prompted to help steer. And despite its generative capabilities, it has little meaningful awareness of the industry it’s operating in.&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%2Fjlbmbnii1xtl0fkl430t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjlbmbnii1xtl0fkl430t.png" alt="ChatGPT's weakness is it doesn't comment on Jeff-the-product-director's cool leather jacket to build rapport." width="612" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ChatGPT's weakness is it doesn't comment on Jeff-the-product-director's cool leather jacket to build rapport.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The developer who seeks to exploit this inherent weakness in AI's ability to build and understand complex relationships will shift their priorities. It will no longer be worth exerting so much effort to write code, because large language models will eventually sufficiently abstract the production of reliable code via natural language. From a programming perspective, it will suffice for the developer to be just expert enough within their technical domain to ensure that the machine does not make any critical technical mistakes.&lt;/p&gt;

&lt;p&gt;More importantly, the developer who is adaptable will leverage their deep understanding of the business domain—an area where AI simply has no ability to compete, at least for the time being. The developer who has genuine interest and empathy for the end-users, the business, and the people working in it, will use AI to build the most effective solutions with 1/10th the effort compared to those who staunchly remain traditional coders—who, in the eyes of the business, will miss the forest for the trees pursuing the dopamine-rush of a puzzle well-solved by their own hands.&lt;/p&gt;

&lt;p&gt;The developers who thrive will be the ones who learn how to collaborate with AI, taking advantage of all of its strengths and its weaknesses.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Skills Will Developers Need?
&lt;/h2&gt;

&lt;p&gt;If AI shifts the nature of programming from "writing code" to "articulating solutions," then the skills developers value today will evolve to universally encompass the soft-skills honed by those who've had time to build software engineering experience in the pre-AI corporate world.&lt;/p&gt;

&lt;p&gt;Initially, the safest group will be senior engineers and managers already celebrated for delivering measurable business impact. They will reap the early benefits of this shift, standing just inches from the sheer edge of a suddenly expanding value chasm that separates them from the incoming junior developers who have had no opportunity to build technical experience or domain knowledge. These newcomers have the grave misfortune of trying to cross a bridge that is suddenly falling apart beneath them.&lt;/p&gt;

&lt;p&gt;But even senior engineers won’t be safe forever. The critical move for senior and junior engineers alike will be to lean heavily on their unique strengths over AI, and offload everything else.&lt;/p&gt;

&lt;p&gt;The ability to articulate a problem clearly and break it down into actionable logical steps will be a key differentiating skill. AI can generate code, but it can’t understand ambiguous or poorly framed requirements. Developers must be highly effective translators of business needs into prompts that AI can act on effectively. They must provide the right amount of technical context so as to not let the AI run amok by either under- or over-engineering a terrible implementation.&lt;/p&gt;

&lt;p&gt;While AI can write individual components of a system, it can’t yet design how all those parts fit together, at least very well. In my personal experience, it loses sight of the bigger picture quickly, and is an indecisive pushover when evaluating important decisions. Developers will need to focus on architecture and integration, ensuring that the pieces generated by AI fit within the broader system and align with organizational 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%2F4nowamvo9bsihbnsd0om.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4nowamvo9bsihbnsd0om.png" alt="We need to refactor this rectangle right here, or we all die instantly." width="612" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We need to refactor this rectangle right here, or we all die instantly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Developers will need to rigorously evaluate and refine AI outputs, ensuring they are efficient, secure, and aligned with business objectives. This will involve a mix of technical expertise and gut intuition honed through experience with production systems.&lt;/p&gt;

&lt;p&gt;The developer who builds trust with stakeholders, understands user pain points, and advocates for solutions that align with company values will have a clear edge. These are not skills an AI can replicate (yet), and they will set the best developers apart. (And arguably, they already do.)&lt;/p&gt;

&lt;p&gt;The measure of success as a developer has never been, and still won't be, how many lines of code you can push—it will be how much impact you can drive. The winners in this new landscape will be those who:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ship solutions that actually solve user problems.&lt;/li&gt;
&lt;li&gt;Build resilient systems that scale with the needs of the business.&lt;/li&gt;
&lt;li&gt;Use AI as a multiplier, not a crutch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a shift from a &lt;strong&gt;craftsman mentality&lt;/strong&gt; to a &lt;strong&gt;strategist mentality&lt;/strong&gt;. The best developers will spend less time manually refactoring and testing, and more time solving meaningful problems. The skill of traditionally writing code will become less and less intrinsically valuable, except in cases where peak technical performance is vital to the business or product strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Will Replace Developers Who Don't Adapt
&lt;/h2&gt;

&lt;p&gt;Here’s the truth: the role of developers isn’t going away, but &lt;strong&gt;what developers do day-to-day will change dramatically.&lt;/strong&gt; The tasks that are repetitive, time-consuming, and easily described will be automated. That’s not a threat—it’s an opportunity.&lt;/p&gt;

&lt;p&gt;Developers who embrace this change will have more time to focus on things that truly matter. Crafting seamless experiences. Discovering innovative solutions. Solving real world problems.&lt;/p&gt;

&lt;p&gt;But those who resist—who double down on manual processes or dismiss the potential of these tools—risk being left behind. AI isn’t waiting for anyone to catch up. If you find yourself scoffing at the imperfect code AI generates today, remember: there was once a great programmer who believed they would always write better assembly than a compiler. We know how that story ended.&lt;/p&gt;

&lt;p&gt;The beauty of this shift is that it lowers barriers and opens the door for anyone willing to learn. Generative AI is a tool—not a replacement—and like every paradigm shift before it, those who embrace it will amplify their problem-solving capabilities. Whether you’re a junior developer just starting out or a seasoned architect, AI offers a way to do more, faster, and with greater focus on what truly matters.&lt;/p&gt;

&lt;p&gt;But succeeding in this new era requires adaptation. You can’t approach AI as just another tool for automation. It’s a collaborator. Learn how to guide it effectively—how to frame problems, validate outputs, and iterate on solutions. Shift your focus from the mechanics of coding to the broader picture: understanding users, designing systems, and aligning with strategy.&lt;/p&gt;

&lt;p&gt;AI is abstracting effort itself, freeing developers to put their energy where it counts: driving real impact. If you can master this transition, you won’t just keep up—you’ll be able to change the world.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Will Amplify Builders—But Replace Manual Work
&lt;/h2&gt;

&lt;p&gt;The highest-performing developers won’t just write code; they’ll use AI to redefine how businesses operate. By leveraging their technical skills in collaboration with AI, they’ll automate the definition and translation of business and user needs, analyze unstructured data to uncover opportunities, and pinpoint inefficiencies in processes. These developers won’t just automate workflows—they’ll effectively automate the organization itself.&lt;/p&gt;

&lt;p&gt;It’s not far-fetched to imagine Sam Altman’s &lt;a href="https://fortune.com/2024/02/04/sam-altman-one-person-unicorn-silicon-valley-founder-myth/" rel="noopener noreferrer"&gt;prediction of a one-person unicorn&lt;/a&gt; becoming reality within the next decade.&lt;/p&gt;

&lt;p&gt;For those in non-technical roles, this should be a wake-up call. Developers using AI won’t just stick to their traditional domains—they’ll expand into others, from marketing and operations to design and even product leadership. Not maliciously, and not intentionally to displace people, but because AI will give them (or the companies that employ them) the tools to radically change manual processes that were once untouchable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What If I’m Not a Developer?
&lt;/h2&gt;

&lt;p&gt;The solution is simple: &lt;strong&gt;learn to build.&lt;/strong&gt; Not necessarily to code like a software engineer, but to design and build systems that solve problems. Start now, before the gap widens.&lt;/p&gt;

&lt;p&gt;AI is transforming the nature of work. Any process that can be automated profitably, likely will be. This isn’t speculation—it’s the trajectory of technological progress. The people who understand how to create, build, and solve problems with these tools will race ahead, automating tasks, increasing productivity, and unlocking entirely new opportunities.&lt;/p&gt;

&lt;p&gt;If you’re in a non-technical role, you might think: "I don’t need to learn to code. AI will handle it for me." That’s partially true—AI tools are lowering the barriers to entry and making it easier to get started. But the people who thrive in this era will be the ones who understand and are well-practiced in the fundamentals of how to build a solution from nothing.&lt;/p&gt;

&lt;p&gt;AI isn’t magic. It doesn’t understand your business, your customers, or your goals. It still relies on human input—on people who can frame problems, validate outputs, and integrate solutions. Developers already know how to do this, and they’re collaborating with AI to push boundaries. You can do it too—it just takes practice and a willingness to adapt.&lt;/p&gt;




&lt;p&gt;Thanks for reading my first article on Dev.to. I genuinely believe the future is bright for all professionals who embrace AI—not just as a tool, but as a partner in solving meaningful problems.&lt;/p&gt;

&lt;p&gt;This paradigm shift isn’t the end of programmers, but it's likely the beginning of a new era of programming. Careers will evolve rapidly. The only constant is change. The key to thriving in this world is adaptability.&lt;/p&gt;

&lt;p&gt;Go build something. It doesn’t matter if you’re an experienced developer or someone who’s never written a line of code. Spend an hour exploring what’s possible. Use AI to solve a problem, automate a tedious task, or create something just for fun.&lt;/p&gt;

&lt;p&gt;The people out there experimenting, learning, and building today—whether they have technical experience or not—are the ones who will thrive tomorrow.&lt;/p&gt;

&lt;p&gt;Be one of them. &lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwaredevelopment</category>
      <category>career</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>The Problem with Handling Node.js Errors in TypeScript (and the workaround)</title>
      <dc:creator>Joseph Barron</dc:creator>
      <pubDate>Wed, 25 Nov 2020 11:06:52 +0000</pubDate>
      <link>https://dev.to/jdbar/the-problem-with-handling-node-js-errors-in-typescript-and-the-workaround-m64</link>
      <guid>https://dev.to/jdbar/the-problem-with-handling-node-js-errors-in-typescript-and-the-workaround-m64</guid>
      <description>&lt;h1&gt;
  
  
  The Setup
&lt;/h1&gt;

&lt;p&gt;So, I was recently using Node's &lt;code&gt;url&lt;/code&gt; module within TypeScript to be able to do some simple validation of user-provided URLs. &lt;a href="https://nodejs.org/api/url.html#url_new_url_input_base" rel="noopener noreferrer"&gt;According to the docs&lt;/a&gt;, when an invalid URL is supplied to the &lt;code&gt;URL&lt;/code&gt; class, it throws a &lt;code&gt;TypeError&lt;/code&gt;. Great! This is exactly what I wanted.&lt;/p&gt;

&lt;p&gt;Next, all I had to do was catch that particular &lt;code&gt;TypeError&lt;/code&gt; and give a helpful message to the user to let them know their URL was no good. Easy, all I need to do is write a &lt;code&gt;try-catch&lt;/code&gt; statement and check the &lt;a href="https://nodejs.org/api/errors.html#errors_error_code" rel="noopener noreferrer"&gt;error's &lt;code&gt;code&lt;/code&gt;&lt;/a&gt;. Of course, the specific error code to look for is &lt;a href="https://nodejs.org/api/all.html#errors_err_invalid_url" rel="noopener noreferrer"&gt;documented on an entirely different page&lt;/a&gt; for some reason. It was actually easier for me to just spin up a terminal and write a gibberish string into a &lt;code&gt;new URL()&lt;/code&gt; call myself to determine that I was looking for &lt;code&gt;"ERR_INVALID_URL"&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Problematic Code
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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;validUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;href&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;e&lt;/span&gt;&lt;span class="p"&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;e&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;TypeError&lt;/span&gt;&lt;span class="p"&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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ERR_INVALID_URL&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="c1"&gt;// Property 'code' does not exist on&lt;/span&gt;
            &lt;span class="c1"&gt;// type 'TypeError'. ts(2339)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Huh? What do you mean? The docs clearly stated that an &lt;code&gt;Error&lt;/code&gt; in Node should have a &lt;code&gt;code&lt;/code&gt; property, and &lt;a href="https://nodejs.org/api/errors.html#errors_class_typeerror" rel="noopener noreferrer"&gt;&lt;code&gt;TypeError&lt;/code&gt; extends &lt;code&gt;Error&lt;/code&gt;&lt;/a&gt;... This didn't make sense. &lt;/p&gt;

&lt;p&gt;I used VS Code's nifty "Go to Definition" feature to find the type definition for &lt;code&gt;TypeError&lt;/code&gt;, which opened &lt;code&gt;node_modules\typescript\lib\lib.es5.d.ts&lt;/code&gt;. I then found my way to the definition for the &lt;code&gt;Error&lt;/code&gt; interface...&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="cm"&gt;/* node_modules\typescript\lib\lib.es5.d.ts */&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh! This was the interface of an &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error" rel="noopener noreferrer"&gt;Error&lt;/a&gt; you'd find in a browser environment.&lt;/p&gt;

&lt;p&gt;But I was working with Node, and I already had the &lt;a href="https://www.npmjs.com/package/@types/node" rel="noopener noreferrer"&gt;@types/node package&lt;/a&gt; installed... I had falsely assumed that this would somehow magically tell the TypeScript linter that I was catching a Node &lt;code&gt;Error&lt;/code&gt;. How was I supposed to get TypeScript to infer that the &lt;code&gt;TypeError&lt;/code&gt; I was handling most likely extended Node's &lt;code&gt;Error&lt;/code&gt; class, and had the extra &lt;code&gt;code&lt;/code&gt; property I was looking for?&lt;/p&gt;

&lt;h1&gt;
  
  
  Search Engine Spelunking
&lt;/h1&gt;

&lt;p&gt;After some confused finagling with my &lt;code&gt;tsconfig.json&lt;/code&gt; and VS Code settings, I quickly gave up and went to Google. I soon after learned two things via random answers on StackOverflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The type definition for the NodeJS &lt;code&gt;Error&lt;/code&gt; class is declared in &lt;code&gt;node_modules\@types\node\globals.d.ts&lt;/code&gt; -- and was accessible as &lt;code&gt;NodeJS.ErrnoException&lt;/code&gt;. I wasn't sure where this was officially documented, but alright!&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* node_modules\@types\node\globals.d.ts */&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ErrnoException&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;errno&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;code&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;path&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;syscall&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It was possible to use &lt;a href="https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards" rel="noopener noreferrer"&gt;TypeScript's type guards&lt;/a&gt; to create a function that I could use to check the error at runtime, so that I (and TypeScript) could be absolutely sure that this variable was a Node &lt;code&gt;Error&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The example function from StackOverflow looked sort of 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="nf"&gt;isError&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="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;NodeJS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ErrnoException&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;error&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Error&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;At a glance, this seemed like it would work... The function was running an &lt;code&gt;instanceof&lt;/code&gt; check and used a "type predicate" (the &lt;code&gt;error is NodeJS.ErrnoException&lt;/code&gt; part) to help TypeScript to do the type inference I was looking for. I could finally access the &lt;code&gt;code&lt;/code&gt; property on the error without any dreaded red squiggly lines.&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;TypeError&lt;/span&gt;&lt;span class="p"&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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ERR_INVALID_URL&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="c1"&gt;// Hooray?&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, I wasn't totally satisfied. For one, there was nothing stopping me from passing things that weren't errors to &lt;code&gt;isError()&lt;/code&gt;. This was easily fixed by changing the the first argument of &lt;code&gt;isError()&lt;/code&gt; to expect &lt;code&gt;Error&lt;/code&gt; instead of &lt;code&gt;any&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Secondly, it also felt inherently silly to have to run two &lt;code&gt;instanceof&lt;/code&gt; checks every time I wanted to handle an error. (Truthfully, it's not the worst thing in the world... but I believe that TypeScript should require developers to make as few runtime code changes as possible when transitioning from JavaScript.)&lt;/p&gt;

&lt;h1&gt;
  
  
  The Solution
&lt;/h1&gt;

&lt;p&gt;After some experimenting, I managed to come up with the following function, which I tested with a couple of custom error classes to ensure that any additionally defined properties were preserved.&lt;/p&gt;

&lt;p&gt;It turned out that the key was to make a &lt;a href="https://www.typescriptlang.org/docs/handbook/generics.html" rel="noopener noreferrer"&gt;generic function&lt;/a&gt; which acted as a typeguarded version of &lt;code&gt;instanceof&lt;/code&gt; for Node.JS error handling, by doing the following things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Accepted two arguments that would be similar to the left-hand and right-hand sides of the &lt;code&gt;instanceof&lt;/code&gt; operator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enforced the first argument was of the &lt;code&gt;Error&lt;/code&gt; class or a subclass.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enforced the second argument was a constructor for an &lt;code&gt;Error&lt;/code&gt; or a subclass of &lt;code&gt;Error&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ran the &lt;code&gt;instanceof&lt;/code&gt; check.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Used a type predicate to intersect the type of the first argument with the instance type of the error constructor in the second argument, as well as &lt;code&gt;NodeJS.ErrnoException&lt;/code&gt; so that type inference would work as expected when used.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * A typeguarded version of `instanceof Error` for NodeJS.
 * @author Joseph JDBar Barron
 * @link https://dev.to/jdbar
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;instanceOfNodeError&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="k"&gt;new &lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Error&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;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;errorType&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="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nb"&gt;InstanceType&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="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;NodeJS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ErrnoException&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;value&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;errorType&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;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Original Use Case
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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;validUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;href&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;e&lt;/span&gt;&lt;span class="p"&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="nf"&gt;instanceOfNodeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TypeError&lt;/span&gt;&lt;span class="p"&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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ERR_INVALID_URL&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="c1"&gt;// Hooray!&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usage with Custom Error Classes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create our custom error classes.&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoolError&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;foo&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;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello world.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VeryCoolError&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CoolError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;bar&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;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Goodbye world.&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="c1"&gt;// Try throwing an error.&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CoolError&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;e&lt;/span&gt;&lt;span class="p"&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="nf"&gt;instanceOfNodeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CoolError&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// typeof e: CoolError &amp;amp; NodeJS.ErrnoException&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;instanceOfNodeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;VeryCoolError&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// typeof e: VeryCoolError &amp;amp; NodeJS.ErrnoException&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// typeof e: any&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="c1"&gt;// Try passing something that's not an error.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;NaN&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="nf"&gt;instanceOfNodeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CoolError&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Argument of type 'number' is not assignable to\&lt;/span&gt;
    &lt;span class="c1"&gt;// parameter of type 'Error'. ts(2345)&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;foo&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;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CoolError&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="nf"&gt;instanceOfNodeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Argument of type 'NumberConstructor' is not assignable&lt;/span&gt;
    &lt;span class="c1"&gt;// to parameter of type 'new (...args: any) =&amp;gt; Error'.&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;foo&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;You might be wondering why in that one &lt;code&gt;else&lt;/code&gt; clause, the type of &lt;code&gt;e&lt;/code&gt; was &lt;code&gt;any&lt;/code&gt;... well, TypeScript can't guarantee the type of &lt;code&gt;e&lt;/code&gt; is anything in particular, because JavaScript lets you &lt;code&gt;throw&lt;/code&gt; literally anything. Thanks JavaScript...&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;After utilizing both generics and type guards, I managed to get TypeScript to correctly infer the shape of the errors I was handling in a Node.js environment without performing redundant &lt;code&gt;instanceof&lt;/code&gt; checks. However, the solution still wasn't perfect, since I probably did sacrifice some amount of compute overhead and space on the call stack to be able to call the &lt;code&gt;instanceOfNodeError()&lt;/code&gt; function compared to the bog-standard &lt;code&gt;instanceof&lt;/code&gt; call I would have done in JavaScript.&lt;/p&gt;




&lt;p&gt;It's possible that in the future, there could be an update to the &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node" rel="noopener noreferrer"&gt;@types/node&lt;/a&gt; package that would merge the &lt;code&gt;NodeJS.ErrnoException&lt;/code&gt; type with the global &lt;code&gt;Error&lt;/code&gt; type. &lt;/p&gt;

&lt;p&gt;One could argue that since not all errors in Node.js will have the &lt;code&gt;code&lt;/code&gt; property (or the other properties on the &lt;code&gt;ErrnoException&lt;/code&gt; type), that it doesn't make sense to do such a reckless merging of types. However, I don't see a lot of harm when all of the properties of &lt;code&gt;ErrnoException&lt;/code&gt; are marked optional.&lt;/p&gt;

&lt;p&gt;Otherwise, they have to be manually added to any modules that might throw an &lt;code&gt;Error&lt;/code&gt; with the properties of &lt;code&gt;ErrnoException&lt;/code&gt;, &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commit/cddd0b7aab18761214d26a0c7012cf45de5285a9" rel="noopener noreferrer"&gt;per the details of this rather old commit responsible for implementing it within the &lt;code&gt;fs&lt;/code&gt; module.&lt;/a&gt; However, this still leaves us with a problem when these &lt;code&gt;ErrnoException&lt;/code&gt; errors can be thrown by the constructors of classes in Node.js, like the &lt;code&gt;URL&lt;/code&gt; class does.&lt;/p&gt;

&lt;p&gt;For that, the only alternative fix I could think of would be for TypeScript to add some sort of &lt;code&gt;throws&lt;/code&gt; syntax for function/constructor signatures -- which there seems to be &lt;a href="https://github.com/microsoft/TypeScript/issues/13219" rel="noopener noreferrer"&gt;an open issue for from 2016 in the microsoft/TypeScript GitHub repo.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>node</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
