<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JavaScript &#8211; Software, Fitness, and Gaming &#8211; Jesse Warden</title>
	<atom:link href="https://jessewarden.com/category/javascript-2/feed" rel="self" type="application/rss+xml" />
	<link>https://jessewarden.com</link>
	<description>Software &#124; Fitness &#124; Gaming</description>
	<lastBuildDate>Sun, 28 Jun 2026 22:08:49 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://jessewarden.com/wp-content/uploads/2016/08/cropped-Lambda2-32x32.png</url>
	<title>JavaScript &#8211; Software, Fitness, and Gaming &#8211; Jesse Warden</title>
	<link>https://jessewarden.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Type Driven Development: Result</title>
		<link>https://jessewarden.com/2026/06/type-driven-development-result.html</link>
					<comments>https://jessewarden.com/2026/06/type-driven-development-result.html#respond</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Sun, 28 Jun 2026 11:18:44 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://jessewarden.com/?p=6980</guid>

					<description><![CDATA[Part 7 &#8211; Result This is a series of posts I&#8217;m writing about using types as another tool in software development, Continuous Delivery, &#38; keeping LLM&#8217;s honest. They&#8217;re also a design &#38; refactoring tool, a communication tool, and reduce how many tests you have to write. Good type systems create pure &#38; total functions. Where [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Part 7 &#8211; Result</h2>



<p class="wp-block-paragraph">This is a series of posts I&#8217;m writing about using types as another tool in software development, Continuous Delivery, &amp; keeping LLM&#8217;s honest. They&#8217;re also a design &amp; refactoring tool, a communication tool, and reduce how many tests you have to write.</p>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>Parts:</strong></summary>
<ol class="wp-block-list">
<li><a href="https://jessewarden.com/2026/06/type-driven-development-branded-types.html">Part 1 &#8211; Branded Types</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-product-types.html">Part 2 &#8211; Product Types</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-unions-and-discriminated-unions.html">Part 3 &#8211; Union &amp; Discriminated Unions</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-non-empty-collections.html">Part 4 &#8211; Non-Empty Collections</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-indexed-types.html">Part 5 &#8211; Indexed Types</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-unknown-vs-any.html">Part 6 &#8211; unknown vs any</a></li>



<li>Part 7 &#8211; Result</li>
</ol>
</details>



<p class="wp-block-paragraph">Good type systems create pure &amp; total functions. Where does that leave errors? In programming, we have 4 types of errors:</p>



<ol class="wp-block-list">
<li>those we create in our domain</li>



<li>those we expect from infrastructure</li>



<li>situations where we cannot recover</li>



<li>those we weren&#8217;t expecting, hence &#8220;exceptional&#8221; situations</li>
</ol>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-794e3cfa wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="588" height="992" src="https://jessewarden.com/wp-content/uploads/2026/06/exception-blindness.png" alt="" class="wp-image-6981" srcset="https://jessewarden.com/wp-content/uploads/2026/06/exception-blindness.png 588w, https://jessewarden.com/wp-content/uploads/2026/06/exception-blindness-178x300.png 178w" sizes="(max-width: 588px) 100vw, 588px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img decoding="async" width="596" height="996" src="https://jessewarden.com/wp-content/uploads/2026/06/result-types.png" alt="" class="wp-image-6982" srcset="https://jessewarden.com/wp-content/uploads/2026/06/result-types.png 596w, https://jessewarden.com/wp-content/uploads/2026/06/result-types-180x300.png 180w" sizes="(max-width: 596px) 100vw, 596px" /></figure>
</div>
</div>



<span id="more-6980"></span>



<p class="wp-block-paragraph">If a type system has Discriminated Unions (sum / variant types), then that&#8217;s what we use for 1 &amp; 2, the majority of what programmers deal w/.</p>


<pre class="wp-block-code"><span><code class="hljs">type FetchError 
  = BadURL 
  | BadBody 
  | BadStatus 
  | NetworkError 
  | Timeout</code></span></pre>


<p class="wp-block-paragraph">Unless you&#8217;re dealing w/important hardware situations like Rust&#8217;s panics, we just ignore 3 b/c you can&#8217;t do anything anyway. 4 will &#8220;go away&#8221; if you focus on 1 &amp; 2.</p>



<p class="wp-block-paragraph">Modelling errors w/Unions poses a problem from a Domain Driven Design perspective: how do you differentiate 2 paths; happy &amp; unhappy? The FP world has settled on a Result type:</p>


<pre class="wp-block-code"><span><code class="hljs language-xml">type Result<span class="hljs-tag">&lt;<span class="hljs-name">T,</span> <span class="hljs-attr">E</span>&gt;</span>
  = Ok<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span>
  | Err<span class="hljs-tag">&lt;<span class="hljs-name">E</span>&gt;</span></code></span></pre>


<p class="wp-block-paragraph">It has 2 type parameters; T type for happy path data, E error type for unhappy path.</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">type FetchResult&lt;<span class="hljs-built_in">Array</span>&lt;Person&gt;, FetchError&gt;</code></span></pre>


<p class="wp-block-paragraph">However, E in practice never is just 1 error for long. As you start composing more functions together that can fail, you start creating anonymous unions. For example, if we read from an environment variable for our secrets:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">type ReadSecrets = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span>
  Result&lt;Secrets, ReadError&gt;</code></span></pre>


<p class="wp-block-paragraph">&#8230; then call fetch, our return type for that function would be both errors:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">type fetchPeople = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> 
  Result&lt;<span class="hljs-built_in">Array</span>&lt;Person&gt;, ReadError | FetchError&gt;</code></span></pre>


<p class="wp-block-paragraph">Those anonymous unions of errors, e.g. <code>ReadError | FetchError</code>, start happening a lot. The type system ensures through exhaustiveness checking you handle all errors. You also discover more about your domain through what can go wrong.</p>



<p class="wp-block-paragraph">Testing is straight forward b/c the happy path is just <code>Ok&lt;T&gt;</code>:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">stubFetch = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> ok(&#91; person ])</code></span></pre>


<p class="wp-block-paragraph">&amp; unhappy is an <code>Err&lt;E&gt;</code>:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">stubBadFetch = <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> err(b00m b00m)</code></span></pre>


<p class="wp-block-paragraph">You still have the flexibility to recover from each error; e.g. if secrets can&#8217;t be read from environment variables, you can fetch from a service. Others, like a fetch error <code>BadStatus&lt;429&gt;</code>, you could retry. Why not try/catch? Result is type safe + ensures all are handled.</p>



<p class="wp-block-paragraph">Result gives you a convention for error handling + separating happy/unhappy paths; u still retain the ability to create DDD Domain errors &#8220;PersonUnauthorized&#8221;, infrastructure &#8220;FetchError&#8221;, &amp; Panics like &#8220;CantReadSecrets&#8221; that u can map to a throw/panic (or Effect.die). You no longer use try/catch unless you&#8217;re mapping known unsafe (or potentially unsafe) code to a Result:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">const</span> json = <span class="hljs-built_in">JSON</span>.parse(data)
  <span class="hljs-keyword">return</span> ok(json)
} <span class="hljs-keyword">catch</span>(error) {
  <span class="hljs-keyword">return</span> err(error)
}</code></span></pre>


<p class="wp-block-paragraph">We&#8217;ll talk more in the future about how to model Errors as Values &amp; build applications on top of Result, and the benefits of doing so.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2026/06/type-driven-development-result.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Type Driven Development: unknown vs any</title>
		<link>https://jessewarden.com/2026/06/type-driven-development-unknown-vs-any.html</link>
					<comments>https://jessewarden.com/2026/06/type-driven-development-unknown-vs-any.html#respond</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Sat, 27 Jun 2026 22:58:47 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://jessewarden.com/?p=6974</guid>

					<description><![CDATA[Part 6 &#8211; unknown vs any This is a series of posts I&#8217;m writing about using types as another tool in software development, Continuous Delivery, &#38; keeping LLM&#8217;s honest. They&#8217;re also a design &#38; refactoring tool, a communication tool, and reduce how many tests you have to write. While good type systems give you confidence [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Part 6 &#8211; unknown vs any</h2>



<p class="wp-block-paragraph">This is a series of posts I&#8217;m writing about using types as another tool in software development, Continuous Delivery, &amp; keeping LLM&#8217;s honest. They&#8217;re also a design &amp; refactoring tool, a communication tool, and reduce how many tests you have to write.</p>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>Parts:</strong></summary>
<ol class="wp-block-list">
<li><a href="https://jessewarden.com/2026/06/type-driven-development-branded-types.html">Part 1 &#8211; Branded Types</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-product-types.html">Part 2 &#8211; Product Types</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-unions-and-discriminated-unions.html">Part 3 &#8211; Union &amp; Discriminated Unions</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-non-empty-collections.html">Part 4 &#8211; Non-Empty Collections</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-indexed-types.html">Part 5 &#8211; Indexed Types</a></li>



<li>Part 6 &#8211; unknown vs any</li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-result.html">Part 7 &#8211; Result</a></li>
</ol>
</details>



<p class="wp-block-paragraph">While good type systems give you confidence &#8220;when it compiles, it works&#8221;, and enables fearless refactoring, we&#8217;re often getting data _into_ our type system that isn&#8217;t typed.</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-794e3cfa wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img decoding="async" width="600" height="996" src="https://jessewarden.com/wp-content/uploads/2026/06/any.png" alt="" class="wp-image-6975" srcset="https://jessewarden.com/wp-content/uploads/2026/06/any.png 600w, https://jessewarden.com/wp-content/uploads/2026/06/any-181x300.png 181w" sizes="(max-width: 600px) 100vw, 600px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="616" height="994" src="https://jessewarden.com/wp-content/uploads/2026/06/unknown.png" alt="" class="wp-image-6976" srcset="https://jessewarden.com/wp-content/uploads/2026/06/unknown.png 616w, https://jessewarden.com/wp-content/uploads/2026/06/unknown-186x300.png 186w" sizes="auto, (max-width: 616px) 100vw, 616px" /></figure>
</div>
</div>



<span id="more-6974"></span>


<pre class="wp-block-code"><span><code class="hljs language-javascript">whatIsThisWhoKnows = <span class="hljs-keyword">await</span> response.json()</code></span></pre>


<p class="wp-block-paragraph">How you handle this depends on the type system, but for Gradually Typed ones like Luau, Python, and TypeScript, you have 2 options with various trade offs: any and unknown (Python calls it Any / object).</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">const</span> person = <span class="hljs-built_in">JSON</span>.parse(data) <span class="hljs-keyword">as</span> any
<span class="hljs-comment">// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Compiler allows this dangerous code </span>
<span class="hljs-comment">// because person's type is any</span>
<span class="hljs-built_in">console</span>.log(person.name)</code></span></pre>


<p class="wp-block-paragraph">Any turns the type system off. This sounds horrifying at first, but it&#8217;s also why gradual type systems are so popular; they enable you to git-r-done, you can integrate w/untyped code namely libraries/modules you didn&#8217;t write, or when dealing w/3rd party data that you aren&#8217;t really sure what the type is.</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">const</span> figureOutWhatThisIs:any = JWT.validate(jsonWebToken) <span class="hljs-keyword">as</span> any
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"figureOutWhatThisIs:"</span>, figureOutWhatThisIs)</code></span></pre>


<p class="wp-block-paragraph">Despite types software has a rule of &#8220;we have to run it to know what it does&#8221; and even in something type-powerful like Elm/Scala/Haskell, sometimes we need to run the code to &#8220;see&#8221; or log the data, especially from some 3rd party / code that isn&#8217;t ours. I can&#8217;t count how many times a REST API said it delivered one thing, but ended up delivering something either slightly or completely different. Other times you just set your types up wrong, and need to test &#8217;em at runtime.</p>



<p class="wp-block-paragraph">That said, if you want to be type-safe, and practice Type Driven Development, you should avoid any. Any turns off the type system, so all the work you did on creating types can be negated by one mis-typed any slipping in. Instead, we should be using types to _narrow_ what we want and instead using the unknown type helps us do that.</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">const</span> person = <span class="hljs-built_in">JSON</span>.parse(data) <span class="hljs-keyword">as</span> unknown
<span class="hljs-comment">// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Compiler does NOT allow this, </span>
<span class="hljs-comment">// have to type narrow first</span>
<span class="hljs-built_in">console</span>.log(person.name)</code></span></pre>


<p class="wp-block-paragraph">For now, recognize any is a tool to explicitly turn off the TypeScript compiler. If you can, try to use unknown instead, and type narrow to what you _think_ it should be. If it fails at runtime, type narrow to that, then try again. This ensures data coming from outside must be type narrowed first, and you can add extra unit &amp; fuzz/property tests on this part as well to help.</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">if</span>(personMaybe
  &amp;&amp; <span class="hljs-keyword">typeof</span> personMaybe === <span class="hljs-string">'object'</span>
  &amp;&amp; <span class="hljs-string">'name'</span> <span class="hljs-keyword">in</span> personMaybe
  &amp;&amp; <span class="hljs-keyword">typeof</span> personMaybe?.name === <span class="hljs-string">'string'</span>) {
    <span class="hljs-comment">// then we're probably safe here </span>
    <span class="hljs-comment">// to cast as a Person</span>
    <span class="hljs-keyword">const</span> person = personMaybe <span class="hljs-keyword">as</span> Person</code></span></pre>


<p class="wp-block-paragraph">However, while type narrowing to help the compiler is powerful, it&#8217;s also fraught with foot guns. We&#8217;ll see how we fix that with schemas.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2026/06/type-driven-development-unknown-vs-any.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Type Driven Development: Indexed Types</title>
		<link>https://jessewarden.com/2026/06/type-driven-development-indexed-types.html</link>
					<comments>https://jessewarden.com/2026/06/type-driven-development-indexed-types.html#respond</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Fri, 26 Jun 2026 14:51:13 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://jessewarden.com/?p=6965</guid>

					<description><![CDATA[Part 5 &#8211; Indexed Types This is a series of posts I&#8217;m writing about using types as another tool in software development, Continuous Delivery, &#38; keeping LLM&#8217;s honest. They&#8217;re also a design &#38; refactoring tool, a communication tool, and reduce how many tests you have to write. When we create Objects, all have the same [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Part 5 &#8211; Indexed Types</h2>



<p class="wp-block-paragraph">This is a series of posts I&#8217;m writing about using types as another tool in software development, Continuous Delivery, &amp; keeping LLM&#8217;s honest. They&#8217;re also a design &amp; refactoring tool, a communication tool, and reduce how many tests you have to write.</p>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>Parts:</strong></summary>
<ol class="wp-block-list">
<li><a href="https://jessewarden.com/2026/06/type-driven-development-branded-types.html">Part 1 &#8211; Branded Types</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-product-types.html">Part 2 &#8211; Product Types</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-unions-and-discriminated-unions.html">Part 3 &#8211; Union &amp; Discriminated Unions</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-non-empty-collections.html">Part 4 &#8211; Non-Empty Collections</a></li>



<li>Part 5 &#8211; Indexed Types</li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-unknown-vs-any.html">Part 6 &#8211; unknown vs any</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-result.html">Part 7 &#8211; Result</a></li>
</ol>
</details>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-794e3cfa wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="590" height="990" src="https://jessewarden.com/wp-content/uploads/2026/06/currency-mixups.png" alt="" class="wp-image-6966" srcset="https://jessewarden.com/wp-content/uploads/2026/06/currency-mixups.png 590w, https://jessewarden.com/wp-content/uploads/2026/06/currency-mixups-179x300.png 179w" sizes="auto, (max-width: 590px) 100vw, 590px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="588" height="990" src="https://jessewarden.com/wp-content/uploads/2026/06/index-types.png" alt="" class="wp-image-6967" srcset="https://jessewarden.com/wp-content/uploads/2026/06/index-types.png 588w, https://jessewarden.com/wp-content/uploads/2026/06/index-types-178x300.png 178w" sizes="auto, (max-width: 588px) 100vw, 588px" /></figure>
</div>
</div>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-794e3cfa wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="588" height="992" src="https://jessewarden.com/wp-content/uploads/2026/06/unit-mixups.png" alt="" class="wp-image-6968" srcset="https://jessewarden.com/wp-content/uploads/2026/06/unit-mixups.png 588w, https://jessewarden.com/wp-content/uploads/2026/06/unit-mixups-178x300.png 178w" sizes="auto, (max-width: 588px) 100vw, 588px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="588" height="990" src="https://jessewarden.com/wp-content/uploads/2026/06/measure.png" alt="" class="wp-image-6969" srcset="https://jessewarden.com/wp-content/uploads/2026/06/measure.png 588w, https://jessewarden.com/wp-content/uploads/2026/06/measure-178x300.png 178w" sizes="auto, (max-width: 588px) 100vw, 588px" /></figure>
</div>
</div>



<span id="more-6965"></span>



<p class="wp-block-paragraph">When we create Objects, all have the same thing in common: &#8220;property name and value&#8221;.</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">person = { <span class="hljs-attr">first</span>: <span class="hljs-string">'Jesse'</span>, <span class="hljs-attr">powerLevel</span>: <span class="hljs-number">9001</span> }</code></span></pre>


<p class="wp-block-paragraph">We access that person&#8217;s first property in 2 ways, either <code>person.first</code>, or <code>person['first']</code>. At runtime, accessing the first property will give us the first&#8217;s value, <code>'Jesse'</code>.</p>



<p class="wp-block-paragraph">Product types are usually a collection of types grouped together:</p>


<pre class="wp-block-code"><span><code class="hljs">type Person = { first: string, powerLevel: 9001 }</code></span></pre>


<p class="wp-block-paragraph">We know how to access object values at runtime, but how do we access type property names?</p>



<p class="wp-block-paragraph">We access them the same way we do objects using the name index method (e.g. <code>person['first']</code>), except it&#8217;s &#8220;type name and type value&#8221;:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">type First = Person&#91;<span class="hljs-string">'first'</span>]</code></span></pre>


<p class="wp-block-paragraph">So type First is also just string. Sadly, u can&#8217;t do First.first, but if you remember &#8220;index&#8221; similar to how you access an Array&#8217;s items, like <code>myList[2]</code>, basically the brackets [], that helps me remember.</p>



<p class="wp-block-paragraph">A Money type may look like this:</p>


<pre class="wp-block-code"><span><code class="hljs language-xml">type Money<span class="hljs-tag">&lt;<span class="hljs-name">C</span>&gt;</span> = { currency: C, amount: number }</code></span></pre>


<p class="wp-block-paragraph">The reason you care about indexing is for some operations you want to keep safe, you need to know specific parts of the type. For Money that&#8217;d be <code>Money['currency']</code>.</p>



<p class="wp-block-paragraph">With money, you don&#8217;t really care a/b the amounts when adding, you first ask &#8220;Are currencies the same type?&#8221; b/c you can&#8217;t just add USD (United States Dollars) + EUR (Euro)&#8217;s together. Each currency is worth a completely different amount. Converting them to &amp; from each other, u have to know the exchange rate. It changes every second so we&#8217;ll assume u got it from somewhere.</p>



<p class="wp-block-paragraph">This business rule, or &#8220;invariant&#8221;, is often baked into money libraries, like dinero.js. However, what a lot of those libraries have in common is they do not enforce those rules in the type system; instead, they go halfway then explode at runtime.</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">a:Money, b:Money</span>):<span class="hljs-title">Money</span> </span>{
  <span class="hljs-keyword">if</span>(a.currency !== b.currency) {
    <span class="hljs-keyword">throw</span> <span class="hljs-built_in">Error</span></code></span></pre>


<p class="wp-block-paragraph">Code like this <em>assumes</em> you&#8217;ll create the same types &amp; ensure you don&#8217;t call add w/USD + EUR. That is not encoding the business logic in the type system. Instead, you&#8217;d do something like:</p>


<pre class="wp-block-code"><span><code class="hljs language-xml">function add<span class="hljs-tag">&lt;<span class="hljs-name">C</span>&gt;</span>(a:Money<span class="hljs-tag">&lt;<span class="hljs-name">C</span>&gt;</span>, b:Money<span class="hljs-tag">&lt;<span class="hljs-name">C</span>&gt;</span>):Money<span class="hljs-tag">&lt;<span class="hljs-name">C</span>&gt;</span> {</code></span></pre>


<p class="wp-block-paragraph">Notice there&#8217;s only one C, or currency type parameter there, not two; so that means u HAVE to pass the same currency to add, USD or EUR. There are additional nuances around TypeScript &amp; other languages inferring C is a Union so it could allow USD; use the <code>NoInfer</code> type for the 2nd parameter, but u get the point: types enforce the business rule. Indexing gives you ability query &amp; refine the types when u&#8217;re working w/2 Product Types + u need to know details abt how to combine them. Math w/Money, math w/ temperatures &amp; measurement (Metric vs Imperial), or account migration &amp; other mapping operations that need to be type safe.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2026/06/type-driven-development-indexed-types.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Type Driven Development: Non-Empty Collections</title>
		<link>https://jessewarden.com/2026/06/type-driven-development-non-empty-collections.html</link>
					<comments>https://jessewarden.com/2026/06/type-driven-development-non-empty-collections.html#respond</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Thu, 25 Jun 2026 12:16:31 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://jessewarden.com/?p=6960</guid>

					<description><![CDATA[Part 4 &#8211; Non-Empty Collections This is a series of posts I&#8217;m writing about using types as another tool in software development, Continuous Delivery, &#38; keeping LLM&#8217;s honest. They&#8217;re also a design &#38; refactoring tool, a communication tool, and reduce how many tests you have to write. Now that we have the Big 3® types [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Part 4 &#8211; Non-Empty Collections</h2>



<p class="wp-block-paragraph">This is a series of posts I&#8217;m writing about using types as another tool in software development, Continuous Delivery, &amp; keeping LLM&#8217;s honest. They&#8217;re also a design &amp; refactoring tool, a communication tool, and reduce how many tests you have to write.</p>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>Parts:</strong></summary>
<ol class="wp-block-list">
<li><a href="https://jessewarden.com/2026/06/type-driven-development-branded-types.html">Part 1 &#8211; Branded Types</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-product-types.html">Part 2 &#8211; Product Types</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-unions-and-discriminated-unions.html">Part 3 &#8211; Union &amp; Discriminated Unions</a></li>



<li>Part 4 &#8211; Non-Empty Collections</li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-indexed-types.html">Part 5 &#8211; Indexed Types</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-unknown-vs-any.html">Part 6 &#8211; unknown vs any</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-result.html">Part 7 &#8211; Result</a></li>
</ol>
</details>



<p class="wp-block-paragraph">Now that we have the Big 3® types covered (Branded &#8220;a thing&#8221;, Product &#8220;this AND that&#8221;, and Union &#8220;this OR that&#8221;), let&#8217;s see what you can do when you combine them with type parameters; like function parameters, except for types.</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-794e3cfa wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="586" height="996" src="https://jessewarden.com/wp-content/uploads/2026/06/empty-collection.png" alt="" class="wp-image-6961" srcset="https://jessewarden.com/wp-content/uploads/2026/06/empty-collection.png 586w, https://jessewarden.com/wp-content/uploads/2026/06/empty-collection-177x300.png 177w" sizes="auto, (max-width: 586px) 100vw, 586px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="598" height="992" src="https://jessewarden.com/wp-content/uploads/2026/06/non-empty-collection.png" alt="" class="wp-image-6962" srcset="https://jessewarden.com/wp-content/uploads/2026/06/non-empty-collection.png 598w, https://jessewarden.com/wp-content/uploads/2026/06/non-empty-collection-181x300.png 181w" sizes="auto, (max-width: 598px) 100vw, 598px" /></figure>
</div>
</div>



<span id="more-6960"></span>



<p class="wp-block-paragraph">Array&#8217;s often hold critical data you need, yet have a flaw: you can&#8217;t guarantee there is anything in the Array. This makes working with Arrays&#8217; a bit painful: you have to check first to see if your item is there, THEN use it:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// check for null</span>
<span class="hljs-keyword">if</span>(data&#91;<span class="hljs-number">0</span>]) {
  …
}</code></span></pre>


<p class="wp-block-paragraph">This gets worse if the Array isn&#8217;t in order:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// find it first</span>
<span class="hljs-keyword">const</span> maybeItem = data.find( <span class="hljs-function"><span class="hljs-params">i</span> =&gt;</span> i.name === <span class="hljs-string">'desire'</span> )
<span class="hljs-comment">// then check for null</span>
<span class="hljs-keyword">if</span>(maybeItem) {
  …
}</code></span></pre>


<p class="wp-block-paragraph">This comes up with UI&#8217;s that have multiple Accounts, or in API&#8217;s when loading Feature Flags; the use case for both is &#8220;give me the important data first, and the remaining data, I can use if I need too later&#8221;. But the data isn&#8217;t shaped like that; it&#8217;s a list you must look inside and verify what you found isn&#8217;t null. Wouldn&#8217;t it be nice if you ALWAYS had at least the data you were looking for, and the rest of the data if you needed it?</p>



<p class="wp-block-paragraph">You have 2 options: a custom Product Type or an Array that can&#8217;t be empty.</p>



<p class="wp-block-paragraph">First option, make a Product Type where the first is always there, and the rest can be empty or full of items:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">type AtLeast1 = { <span class="hljs-attr">item</span>: ?, <span class="hljs-attr">data</span>: <span class="hljs-built_in">Array</span> }</code></span></pre>


<p class="wp-block-paragraph">But… what <em>type</em> of item is there, and full of what <em>type</em> of items? For that, we need a parameter to customize the type to whatever we need, so we&#8217;ll add a type parameter, usually called &#8220;T&#8221; which is short for &#8220;Type&#8221; (yes, it&#8217;s uppercased unlike TypeScript/Python/Lua/Ruby/etc function parameters). In TypeScript, Luau, and other languages, parameters are usually parentheses like (one, two), whereas type parameters use the less than and greater than symbols like .</p>


<pre class="wp-block-code"><span><code class="hljs language-xml">type AtLeast1 = { item: T, data: Array<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span> }</code></span></pre>


<p class="wp-block-paragraph">Using it:</p>


<pre class="wp-block-code"><span><code class="hljs">type AtLeast1Account = AtLeast1</code></span></pre>


<p class="wp-block-paragraph">Now, you&#8217;re guaranteed to have the data you need, but the rest is there if you need it:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> good</span>
<span class="hljs-keyword">const</span> account1 = { 
  <span class="hljs-attr">item</span>: primaryAccount, 
  <span class="hljs-attr">data</span>: &#91; secondaryAccount ] 
}

<span class="hljs-comment">// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> also good</span>
<span class="hljs-keyword">const</span> account2 = { 
  <span class="hljs-attr">item</span>: anotherPrimaryAccount, 
  <span class="hljs-attr">data</span>: &#91;] 
}</code></span></pre>


<p class="wp-block-paragraph">The other option… define an Array where it HAS TO HAVE at least 1 item:</p>


<pre class="wp-block-code"><span><code class="hljs language-php">type NonEmptyArray = &#91; T, …<span class="hljs-keyword">Array</span>&#91;T] ]

<span class="hljs-comment">// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> does not compile</span>
<span class="hljs-keyword">const</span> <span class="hljs-keyword">empty</span>:NonEmptyArray&lt;string&gt; = &#91;]

<span class="hljs-comment">// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> compiles</span>
<span class="hljs-keyword">const</span> hasOne:NonEmptyArray&lt;string&gt; = &#91;<span class="hljs-string">"<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f42e.png" alt="🐮" class="wp-smiley" style="height: 1em; max-height: 1em;" />"</span>]</code></span></pre>


<p class="wp-block-paragraph">You can see now that you have the basic core types of Branded, Product, and Union/Discriminated Unions, once you combine with Type Parameters, you can create all kinds of types to ensure the data is in the shape of what you need and the types are easier to work with while flexible for your needs.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2026/06/type-driven-development-non-empty-collections.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Type Driven Development: Unions and Discriminated Unions</title>
		<link>https://jessewarden.com/2026/06/type-driven-development-unions-and-discriminated-unions.html</link>
					<comments>https://jessewarden.com/2026/06/type-driven-development-unions-and-discriminated-unions.html#respond</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Thu, 25 Jun 2026 11:39:10 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://jessewarden.com/?p=6955</guid>

					<description><![CDATA[Part 3 &#8211; Unions &#38; Discriminated Unions This is a series of posts I&#8217;m writing about using types as another tool in software development, Continuous Delivery, &#38; keeping LLM&#8217;s honest. They&#8217;re also a design &#38; refactoring tool, a communication tool, and reduce how many tests you have to write. Branded types allow us to differentiate [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Part 3 &#8211; Unions &amp; Discriminated Unions</h2>



<p class="wp-block-paragraph">This is a series of posts I&#8217;m writing about using types as another tool in software development, Continuous Delivery, &amp; keeping LLM&#8217;s honest. They&#8217;re also a design &amp; refactoring tool, a communication tool, and reduce how many tests you have to write.</p>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>Parts:</strong></summary>
<ol class="wp-block-list">
<li><a href="https://jessewarden.com/2026/06/type-driven-development-branded-types.html">Part 1 &#8211; Branded Types</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-product-types.html">Part 2 &#8211; Product Types</a></li>



<li>Part 3 &#8211; Union &amp; Discriminated Unions</li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-non-empty-collections.html">Part 4 &#8211; Non-Empty Collections</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-indexed-types.html">Part 5 &#8211; Indexed Types</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-unknown-vs-any.html">Part 6 &#8211; unknown vs any</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-result.html">Part 7 &#8211; Result</a></li>
</ol>
</details>



<p class="wp-block-paragraph">Branded types allow us to differentiate between things &amp; Product Types what things belong together. Unions/Discriminated Unions help us narrow things, identifying &#8220;what things are allowed?&#8221;</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-794e3cfa wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="590" height="994" src="https://jessewarden.com/wp-content/uploads/2026/06/Screenshot-2026-06-25-at-7.38.40-AM.png" alt="" class="wp-image-6958" srcset="https://jessewarden.com/wp-content/uploads/2026/06/Screenshot-2026-06-25-at-7.38.40-AM.png 590w, https://jessewarden.com/wp-content/uploads/2026/06/Screenshot-2026-06-25-at-7.38.40-AM-178x300.png 178w" sizes="auto, (max-width: 590px) 100vw, 590px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="582" height="994" src="https://jessewarden.com/wp-content/uploads/2026/06/discriminated-union.png" alt="" class="wp-image-6957" srcset="https://jessewarden.com/wp-content/uploads/2026/06/discriminated-union.png 582w, https://jessewarden.com/wp-content/uploads/2026/06/discriminated-union-176x300.png 176w" sizes="auto, (max-width: 582px) 100vw, 582px" /></figure>
</div>
</div>



<span id="more-6955"></span>



<p class="wp-block-paragraph"><code>type AccountType = string</code> means &#8220;Primary&#8221;, &#8220;Secondary&#8221;, and &#8220;Authorized&#8221; is fine, but so is &#8220;moo&#8221;, &#8220;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f404.png" alt="🐄" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8221;, &amp; &#8220;&#8221;. That doesn&#8217;t restrict things enough. If our API&#8217;s only support those 3 account types, then we need a Union:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">type AccountType = <span class="hljs-string">"Primary"</span> | <span class="hljs-string">"Secondary"</span> | <span class="hljs-string">"Authorized"</span></code></span></pre>


<p class="wp-block-paragraph">Unions come w/Exhaustiveness Checking so you no longer need to write a default case when you pattern match on what the type is:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">switch</span>(accountType) {
  <span class="hljs-keyword">case</span> <span class="hljs-string">"Primary"</span>: …
  <span class="hljs-keyword">case</span> <span class="hljs-string">"Secondary"</span>: …
  <span class="hljs-keyword">case</span> <span class="hljs-string">"Authorized"</span>: …
}</code></span></pre>


<p class="wp-block-paragraph">The compiler ensures you handled all 3, default isn&#8217;t needed, &amp; later when you add or change one, the compiler ensures all places that inspect the AccountType are updated. Useful for both encoding business rules, replacing magic strings w/&#8221;only these strings&#8221;, &amp; help you have a place for additional domain discovery.</p>



<p class="wp-block-paragraph">Discriminated Unions are often used to make Impossible Situations Impossible. In modelling state in UI&#8217;s you may have:</p>


<pre class="wp-block-code"><span><code class="hljs">type Request = {
  loading: boolean
  data?: User
  error?: string
}</code></span></pre>


<p class="wp-block-paragraph">But states like this are possible &amp; you must write unit tests to ensure they&#8217;re not &amp; hope you don&#8217;t miss one:</p>


<pre class="wp-block-code"><span><code class="hljs language-css">{
  <span class="hljs-attribute">loading</span>: true,
  data: user,
  error: <span class="hljs-string">"failed"</span>
}</code></span></pre>


<p class="wp-block-paragraph">Instead, you can ensure those states can&#8217;t possibly happen, AND those states can&#8217;t access data they&#8217;re not allowed to:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">type Request =
| { <span class="hljs-attr">tag</span>: <span class="hljs-string">"loading"</span> }
| { <span class="hljs-attr">tag</span>: <span class="hljs-string">"success"</span>; data: User }
| { <span class="hljs-attr">tag</span>: <span class="hljs-string">"error"</span>; error: string }</code></span></pre>


<p class="wp-block-paragraph">Only the error state can access the error, only the success state can access data. If you mess it up in switch or if statements while type narrowing, the compiler will tell you and won&#8217;t compile the code:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">switch</span>(request.tag) {
  …
  <span class="hljs-keyword">case</span> <span class="hljs-string">"success"</span>:
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Error</span> <span class="hljs-attr">data</span>=<span class="hljs-string">{request</span> <span class="hljs-attr">.</span> <span class="hljs-attr">error</span>} /&gt;</span></span>
    <span class="hljs-comment">// ❌ fails to compile, error does not exist on Success</span>
  <span class="hljs-keyword">case</span> <span class="hljs-string">"error"</span>:
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Success</span> <span class="hljs-attr">data</span>=<span class="hljs-string">{request</span> <span class="hljs-attr">.</span> <span class="hljs-attr">data</span>} /&gt;</span></span> 
    <span class="hljs-comment">// ❌ fails to compile, data does not exist on Error</span>

<span class="hljs-keyword">switch</span>(request.tag) {
  …
  <span class="hljs-keyword">case</span> <span class="hljs-string">"success"</span>:
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Success</span> <span class="hljs-attr">data</span>=<span class="hljs-string">{request</span> <span class="hljs-attr">.</span> <span class="hljs-attr">data</span>} /&gt;</span></span> <span class="hljs-comment">// ✅ works </span>
  <span class="hljs-keyword">case</span> <span class="hljs-string">"error"</span>:
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Error</span> <span class="hljs-attr">data</span>=<span class="hljs-string">{request</span> <span class="hljs-attr">.</span> <span class="hljs-attr">error</span>} /&gt;</span></span> <span class="hljs-comment">// ✅ works</span></code></span></pre>


<p class="wp-block-paragraph">They&#8217;re also great for replacing Maybe&#8217;s (a nicer null). Instead of:</p>



<p class="wp-block-paragraph">User | null</p>



<p class="wp-block-paragraph">We can use:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">type UserLookup =
| Found
| NotFound
type Found = { <span class="hljs-attr">tag</span>: <span class="hljs-string">'found'</span>; user: User }
type NotFound = { <span class="hljs-attr">tag</span>: <span class="hljs-string">'not-found'</span> }</code></span></pre>


<p class="wp-block-paragraph">Unions determine what is allowed &amp; Discriminated Unions enhance that by defining what data is allowed in each alternative. Product Types are often called AND types like &#8220;this <em>and</em> that&#8221; while Unions are called OR types like &#8220;this <em>or</em> that&#8221;.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2026/06/type-driven-development-unions-and-discriminated-unions.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
