<?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: Josiah Nunemaker</title>
    <description>The latest articles on DEV Community by Josiah Nunemaker (@josnun).</description>
    <link>https://dev.to/josnun</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%2F223798%2F3d9bf7e0-9191-478b-b3e0-8ad07f17bd92.jpg</url>
      <title>DEV Community: Josiah Nunemaker</title>
      <link>https://dev.to/josnun</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/josnun"/>
    <language>en</language>
    <item>
      <title>There will still be art in software</title>
      <dc:creator>Josiah Nunemaker</dc:creator>
      <pubDate>Tue, 05 May 2026 21:47:47 +0000</pubDate>
      <link>https://dev.to/josnun/there-will-still-be-art-in-software-388g</link>
      <guid>https://dev.to/josnun/there-will-still-be-art-in-software-388g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://josnun.com/writing/there-will-still-be-art-in-software/" rel="noopener noreferrer"&gt;josnun.com&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Larger groups gaining access to tools and capabilities that were previously exclusive to the elite is no new phenomenon. Books and literacy, photography, manufacturing (eg, 3D printing), and computing are all examples of capabilities that used to be out of reach of the average person, but are now commonplace. With the advent of AI, the next capability to become democratized is seemingly software. &lt;/p&gt;

&lt;p&gt;With each of these shifts, there have been some naysayers declaring that giving "commonfolk" these tools will destroy the craft, wipe out an entire category of jobs, spoil the capabilities, or otherwise lead to the destruction of society as we know it. To some extent, this holds true, but broadly speaking, the democratization has enabled new opportunities for the common man, while still making space for those who excel at their craft. Just because everyone has a phone with a camera doesn't mean there isn't a place for photographers. Their understanding of composition and what makes a good photo is what sets them apart. That's only learned through effort, practice, study, and more practice. One doesn't become an expert photographer just because they have a camera.&lt;/p&gt;

&lt;p&gt;The same will hold true for software. AI makes building software seem easy. And that's great. I'm all for a whole army of people building software that meets their needs, and frees them up to do the work that sets them apart; whether that's getting better at their job, hobbies, or spending time with their families and communities. Quality software is hard to build, though. There's a difference between something that "works" and something that works well. The differentiator is quality and attention to detail. Good software is more than just some code slung on a page. There's design, UX, discovering what &lt;em&gt;doesn't&lt;/em&gt; work, iteration. Using it, and discovering that what you thought you wanted isn't what you actually wanted; what doesn't "feel" right. On some level, there's an intuition that you build after doing the reps of building software. It's learning when to trust your intuition, and when you need to prove it.&lt;/p&gt;

&lt;p&gt;Everyone having the capability to build software is a good thing. There are whole categories of software that would be nice to have, but aren't financially viable to build a business around. Let the people build it themselves. There may be some people out there whose expertise in other disciplines have made them masters of building good software, but the high barrier to entry has kept them away. People have ideas. Maybe their ability to execute on those ideas will unlock whole new categories of tools and software. I expect that, just like with books, software that has had heart and soul poured into it and is a cut above the rest will rise to the top, raising software quality for everyone.&lt;/p&gt;

&lt;p&gt;When everyone can produce, quality becomes the differentiator. Great software makes you &lt;em&gt;feel&lt;/em&gt; things; it's art. That's why I'm hopeful. There's a certain joy that I've been able to unlock by building what lives in my imagination, and I'm excited to see that joy come to others. Will this transition be smooth? I doubt it. I'm sure there will be rough spots and setbacks, but the promise of a new class of software and the potential for refined craft still leaves me optimistic.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>uidesign</category>
    </item>
    <item>
      <title>You don't need TypeScript's index types (probably)</title>
      <dc:creator>Josiah Nunemaker</dc:creator>
      <pubDate>Tue, 22 Oct 2019 00:27:03 +0000</pubDate>
      <link>https://dev.to/josnun/you-don-t-need-typescript-s-index-types-probably-hl</link>
      <guid>https://dev.to/josnun/you-don-t-need-typescript-s-index-types-probably-hl</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally posted on &lt;a href="https://josnun.com/posts/you-dont-need-typescripts-index-types-probably/"&gt;JosNun.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;TypeScript's index types seem super useful when you first find out about them. If you aren't familiar with index types, here's a crash course 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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;StringArray&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&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="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;StringArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;two&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// This isn't valid&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;three&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;three&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;As you can see, &lt;code&gt;StringArray&lt;/code&gt; in our example allows any number to be a property name (key), and any string to be a value. &lt;/p&gt;

&lt;p&gt;Index types are really handy when you have an object that could have unknown keys. They're also handy when using an object as a dictionary or associative array. They do have some downsides, though. You can't specify what keys can be used, and the syntax is also a bit verbose, in my opinion. TypeScript provides a solution, however; the &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt"&gt;&lt;code&gt;Record&lt;/code&gt;&lt;/a&gt; utility.&lt;/p&gt;

&lt;p&gt;In it's simplest form, &lt;code&gt;Record&lt;/code&gt; is very similar to an index type. Let's give it a look:&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;StringArray&lt;/span&gt; &lt;span class="o"&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;number&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="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;StringArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;two&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// This isn't valid&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;three&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;three&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;Like with the index type, &lt;code&gt;arr&lt;/code&gt; can have any number as a key, and any string as a value. For a simple example like this, &lt;code&gt;Record&lt;/code&gt; merely does some cleanup. There are some things that &lt;code&gt;Record&lt;/code&gt; can do, that index types can't very easily, however. One such example is specifying which keys are allowed with a union 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="c1"&gt;// Ain't gonna work&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;TypedKeys&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// An index signature parameter type must be 'string' or 'number'&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Works, but is verbose&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;TypedKeys&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="mi"&gt;0&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Works, and is nice and concise&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;TypedKeys&lt;/span&gt; &lt;span class="o"&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="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&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="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TypedKeys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// Object literal may only specify known properties, and '2' does not exist in type 'Record&amp;lt;0 | 1, string&amp;gt;'&lt;/span&gt;
  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;two&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;You could also use a more advanced type for the value of a &lt;code&gt;Record&lt;/code&gt; as well. At first glance, there may be some downsides. It isn't immediately obvious how you could have some predefined keys, like with an index type. Nevertheless, it's still doable, though maybe not as elegant as with an index 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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;TypedKeys&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zero&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&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="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Same as above&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;TypedKeys&lt;/span&gt; &lt;span class="o"&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;number&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;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zero&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TypedKeys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;three&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;So there you have it, that's TypeScript's &lt;code&gt;Record&lt;/code&gt; utility! Hopefully you'll find new ways to use it to make your code more readable and concise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Maybe a bit of pun intended&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Record&lt;/code&gt; is, in it's simplest form, an easier to read version of index types&lt;/li&gt;
&lt;li&gt;It makes specifying the keys and values much easier when you have complex types&lt;/li&gt;
&lt;li&gt;Fewer characters = quicker to type for most people&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Record&lt;/code&gt; works well with intersection and union types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thoughts? Questions? Let me know in the comments!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Also, I've been thinking about doing regular posts on handy TypeScript utilities or features. If you think you'd find that useful or interesting, let me know in the comments as well!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>tip</category>
      <category>utility</category>
    </item>
    <item>
      <title>What is TypeScript's Exclude?</title>
      <dc:creator>Josiah Nunemaker</dc:creator>
      <pubDate>Thu, 05 Sep 2019 00:24:40 +0000</pubDate>
      <link>https://dev.to/josnun/what-is-typescript-s-exclude-8e9</link>
      <guid>https://dev.to/josnun/what-is-typescript-s-exclude-8e9</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally posted on &lt;a href="https://josnun.com/posts/what-is-typescripts-exclude"&gt;JosNun.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I'm going to be honest, here. I &lt;em&gt;love&lt;/em&gt; TypeScript, but some of the docs for their utility methods aren't that great. Thankfully, they have examples, but sometimes, even those aren't that helpful. &lt;code&gt;Exclude&lt;/code&gt; is one of those utility methods that always had an air of ambiguity around it for me, but recently I did some research, and what I found makes writing some types so much cleaner.&lt;/p&gt;

&lt;p&gt;So what does exclude do? Well, &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html#excludetu"&gt;here's what the docs say&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Exclude&amp;lt;T, U&amp;gt;&lt;/code&gt;: Constructs a type by excluding from T all properties that are assignable to U.'&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not terribly descriptive, but at least it points us in the right direction. In my opinion, the type definition of &lt;code&gt;Exclude&lt;/code&gt; is much more helpful.&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="nb"&gt;Exclude&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="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;U&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;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;U&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;never&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simple way of putting it is that if &lt;code&gt;TypeA&lt;/code&gt; is a subtype of &lt;code&gt;TypeB&lt;/code&gt;, it gets removed. Here's an 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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Widget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;doesStuff&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Doodad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;symbol&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Widget&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PropertyAccessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Exclude&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Doodad&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;object&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;// string | number | symbol&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ExcludeWidget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Exclude&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Doodad&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Widget&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;// string | number | symbol | object;&lt;/span&gt;

&lt;span class="kd"&gt;const&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;PropertyAccessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;key&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="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropertyAccessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&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;symbol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropertyAccessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Symbol&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;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropertyAccessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt; &lt;span class="c1"&gt;// Type '{}' is not assignable to type 'symbol'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;widget&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropertyAccessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;doesStuff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// Type '{ doesStuff: boolean; }' is not assignable to type 'string | number | symbol'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExcludeWidget&lt;/span&gt; &lt;span class="o"&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;widget2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropertyAccessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;doesStuff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Widget&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As shown in the example, the &lt;code&gt;Exclude&lt;/code&gt;, helper enables us to remove a type from a type union. Now, you may be surprised to see that the &lt;code&gt;Widget&lt;/code&gt; interface is not included in the type &lt;code&gt;PropertyAccessor&lt;/code&gt;. This is because an interface extends an object. The same would happen if the interface was declared as a type instead of an interface. On the flipside, however, if we were to exclude &lt;code&gt;Widget&lt;/code&gt; from &lt;code&gt;Doodad&lt;/code&gt; instead of &lt;code&gt;object&lt;/code&gt;, both &lt;code&gt;obj2&lt;/code&gt; and &lt;code&gt;widget2&lt;/code&gt; would be perfectly valid. &lt;code&gt;obj2&lt;/code&gt; being allowed makes sense, since it's type is in the union. &lt;code&gt;widget&lt;/code&gt;, though?! We excluded that type explicitely!&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;Widget&lt;/code&gt; is excluded, &lt;code&gt;object&lt;/code&gt; is still a valid type for &lt;code&gt;ExcludeWidget&lt;/code&gt;. &lt;code&gt;Widget&lt;/code&gt;s are subtypes of &lt;code&gt;object&lt;/code&gt; however, so since object is valid, so are &lt;code&gt;Widgets&lt;/code&gt;;&lt;/p&gt;

&lt;p&gt;After my research and tinkering, I discovered that the name &lt;code&gt;Exclude&lt;/code&gt; is very applicable for what the utility does. Hopefully now you have a better understanding of the way that &lt;code&gt;Exclude&lt;/code&gt; works, and you'll be able to utilize it to write cleaner, simpler types without getting frustrated when that type you excluded is still perfectly valid ;).&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>utility</category>
    </item>
  </channel>
</rss>
