<?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>Software, Fitness, and Gaming &#8211; Jesse Warden</title>
	<atom:link href="https://jessewarden.com/feed" rel="self" type="application/rss+xml" />
	<link>https://jessewarden.com</link>
	<description>Software &#124; Fitness &#124; Gaming</description>
	<lastBuildDate>Tue, 30 Jun 2026 12:24:06 +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>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: Total Function</title>
		<link>https://jessewarden.com/2026/06/type-driven-development-total-function.html</link>
					<comments>https://jessewarden.com/2026/06/type-driven-development-total-function.html#respond</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Tue, 30 Jun 2026 12:21:41 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://jessewarden.com/?p=7003</guid>

					<description><![CDATA[Part 9 &#8211; Total Function This is a series of posts I’m writing about using types as another tool in software development, Continuous Delivery, &#38; keeping LLM’s honest. They’re also a design &#38; refactoring tool, a communication tool, and reduce how many tests you have to write. Type safety is a spectrum. A gradual type [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Part 9 &#8211; Total Function</h2>



<p class="wp-block-paragraph">This is a series of posts I’m writing about using types as another tool in software development, Continuous Delivery, &amp; keeping LLM’s honest. They’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><a href="https://jessewarden.com/2026/06/type-driven-development-result.html">Part 7 &#8211; Result</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-schema.html">Part 8 &#8211; Schema</a></li>



<li>Part 9 &#8211; Total Function</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 fetchpriority="high" decoding="async" width="594" height="996" src="https://jessewarden.com/wp-content/uploads/2026/06/partial-functions.png" alt="" class="wp-image-7009" srcset="https://jessewarden.com/wp-content/uploads/2026/06/partial-functions.png 594w, https://jessewarden.com/wp-content/uploads/2026/06/partial-functions-179x300.png 179w" sizes="(max-width: 594px) 100vw, 594px" /></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="600" height="996" src="https://jessewarden.com/wp-content/uploads/2026/06/total-functions.png" alt="" class="wp-image-7010" srcset="https://jessewarden.com/wp-content/uploads/2026/06/total-functions.png 600w, https://jessewarden.com/wp-content/uploads/2026/06/total-functions-181x300.png 181w" sizes="(max-width: 600px) 100vw, 600px" /></figure>
</div>
</div>



<p class="wp-block-paragraph">Type safety is a spectrum. A gradual type system widens the spectrum in a good &amp; bad way; u have flexibility to discover your domain as it emerges w/less strict types + integrate w/less typed &amp; legacy systems. That has a cost in safety. Sometimes u can narrow what&#8217;s allowed through types, then expand to other possibilities as you learn more. Whatever you choose, aim to design Total Functions; every input returns a <em>sensible</em> value.</p>



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



<p class="wp-block-paragraph">Most functions we create are called Partial Functions; functions that throw/crash, or return nonsensical inputs for some inputs.</p>



<p class="wp-block-paragraph">type Divide = (a:number, b:number) =&gt; number</p>



<p class="wp-block-paragraph">Divide looks like a normal function; notice I only provided the type signature. From that you can figure out how the function works:</p>



<p class="wp-block-paragraph">divide(12, 6) // 2<br>divide(2, 1) // 2</p>



<p class="wp-block-paragraph">What about 2 / 0? That&#8217;s infinity. Technically it&#8217;s a number type, but is that what I want? What about 0 / 0? That&#8217;s NaN. While it&#8217;s called &#8220;NOT a number&#8221;, it&#8217;s also technically a number. Perhaps I just want numbers I can show the user? That means division can fail, so let&#8217;s fix the type:</p>



<p class="wp-block-paragraph">type Divide = (…, …) =&gt; Result<br>divide = (a, b) =&gt; {<br>let n = a / b<br>if(nIsAGoodInteger(n)) {<br>return ok(n)<br>} else {<br>return err(…)<br>}</p>



<p class="wp-block-paragraph">Now it&#8217;s more clear; infinity, negative infinity, &amp; NaN will cause an error. But this is awkward to use; math requires error checking now? Blech… what if we ensure the inputs are good instead?</p>



<p class="wp-block-paragraph">type Divide = (a:number, b:PositiveInteger) =&gt; number</p>



<p class="wp-block-paragraph">Much easier to work w/ + expected outputs. More total.</p>



<p class="wp-block-paragraph">What about fetch? Many would say:</p>



<p class="wp-block-paragraph">type fetch = (url:string) =&gt; Promise</p>



<p class="wp-block-paragraph">but technically it can also crash; u have no internet, u provide a bad URL, JSON fails to parse, blah blah blah. A more total signature would be:</p>



<p class="wp-block-paragraph">type safeFetch = (url:string) =&gt; ResultAsync</p>



<p class="wp-block-paragraph">We &#8220;expect&#8221; some type to be returned from our service; that implies a Schema is involved. It&#8217;s not a Result, but a ResultAsync, which implies a Promise. The error is specifically a FetchError type. The name has &#8220;safe&#8221; in it, implying no exceptions thrown. All that from just reading the type signature. More total.</p>



<p class="wp-block-paragraph">Partial functions have type signatures that lie to you. They say &#8220;Oh yeah I return a Promise&#8221;, but all kinds of bad things happen the type signature doesn&#8217;t tell you about. The ResultAsync is extremely clear &amp; thorough.</p>



<p class="wp-block-paragraph">Once u start composing these functions together to make programs, that makes your code more total. &#8220;when it compiles it works&#8221; is more likely to be true. Your app&#8217;s type signature, whether UI or API, is more likely to be total.</p>



<p class="wp-block-paragraph">type AWSLambda = (event:APIGatewayProxyEvent) =&gt; ResultAsync</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2026/06/type-driven-development-total-function.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Type Driven Development: Schema</title>
		<link>https://jessewarden.com/2026/06/type-driven-development-schema.html</link>
					<comments>https://jessewarden.com/2026/06/type-driven-development-schema.html#respond</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Tue, 30 Jun 2026 12:18:03 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://jessewarden.com/?p=7004</guid>

					<description><![CDATA[Part 8 &#8211; Schema 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. To do anything of value in software, we have [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Part 8 &#8211; Schema</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><a href="https://jessewarden.com/2026/06/type-driven-development-result.html">Part 7 &#8211; Result</a></li>



<li>Part 8 &#8211; Schema</li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-total-function.html">Part 9 &#8211; Total Function</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 decoding="async" width="592" height="990" src="https://jessewarden.com/wp-content/uploads/2026/06/drift.png" alt="" class="wp-image-7005" srcset="https://jessewarden.com/wp-content/uploads/2026/06/drift.png 592w, https://jessewarden.com/wp-content/uploads/2026/06/drift-179x300.png 179w" sizes="(max-width: 592px) 100vw, 592px" /></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="594" height="992" src="https://jessewarden.com/wp-content/uploads/2026/06/schema.png" alt="" class="wp-image-7006" srcset="https://jessewarden.com/wp-content/uploads/2026/06/schema.png 594w, https://jessewarden.com/wp-content/uploads/2026/06/schema-180x300.png 180w" sizes="auto, (max-width: 594px) 100vw, 594px" /></figure>
</div>
</div>



<p class="wp-block-paragraph">To do anything of value in software, we have to get unsafe data from outside our type system into it. We saw how unknown forces us to type narrow, but type narrowing is dangerous, tedious, and it&#8217;s hard to be thorough.</p>



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


<pre class="wp-block-code"><span><code class="hljs language-javascript">cow = <span class="hljs-built_in">JSON</span>.parse(json)
<span class="hljs-keyword">if</span>(cow 
  &amp;&amp; <span class="hljs-string">'age'</span> <span class="hljs-keyword">in</span> cow 
  &amp;&amp; <span class="hljs-keyword">typeof</span> cow?.age === <span class="hljs-string">'number'</span>)
  <span class="hljs-comment">// could be NaN</span></code></span></pre>


<p class="wp-block-paragraph">Then comes the architecture problem; how do you DRY (Don&#8217;t Repeat Yourself) this? Multiple parts of your code have:</p>


<pre class="wp-block-code"><span><code class="hljs">type Cow = { age: number }</code></span></pre>


<p class="wp-block-paragraph">But later the back-end changes age to be optional:</p>


<pre class="wp-block-code"><span><code class="hljs">type Cow = { age?: number }</code></span></pre>


<p class="wp-block-paragraph">So you have to update both your types and parsing code. This occurs a lot, which then creates Shotgun Parsing all throughout your code:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">if</span>(cow.age) {
  <span class="hljs-comment">// use age</span>
} <span class="hljs-keyword">else</span> {
  <span class="hljs-comment">// throw an error</span>
}</code></span></pre>


<p class="wp-block-paragraph">This is because despite types, no one can trust the data. No code knows where the data came from; &#8220;Maybe age hasn&#8217;t been validated yet? Better validate just in case.&#8221; You started coupling the types through your code in hopes everyone would know &#8220;what a Cow is&#8221;, but now all the code is repeatedly validating the data. Worse, only parts are validated:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">if</span>(cow.name) {
<span class="hljs-comment">// if no name, throws an error</span>
<span class="hljs-comment">// what about age? Who knows</span></code></span></pre>


<p class="wp-block-paragraph">Even code formatting, e.g. Oxcfmt/Prettier/Biome, is bypassed b/c data is at runtime, so Python snake case data:</p>


<pre class="wp-block-code"><span><code class="hljs language-css">{ <span class="hljs-attribute">first_name</span>: <span class="hljs-string">'Moo'</span>, last_name: <span class="hljs-string">'Cow'</span> }</code></span></pre>


<p class="wp-block-paragraph">Can start infecting your camelCase style code. Since validation is often impromptu, it&#8217;s not all the same or thorough. Empty strings &#8221;, NaN for numbers, and optional properties on data cause runtime errors or null checks like <code>if(thing?.and?.some?.prop)</code> adding lots of validation code repeatedly.</p>



<p class="wp-block-paragraph">Lastly, the data you get isn&#8217;t always what you want. REST API&#8217;s can send back 100 JSON values, but you only need 2, forcing you to write &amp; maintain a lot of parsing code you&#8217;ll never use. JSON can have optional values, but you require that data, knowingly parsing the thing you don&#8217;t like.</p>



<p class="wp-block-paragraph">Schema&#8217;s solve all this. 1 source of truth, it either parses or it doesn&#8217;t, the type is validated data all of your code can trust, use without modifying, and not have to validate. The shape can be what you want/need instead of coupling to what the back-end gives you, then having to update all your code when the back-end changes. Zod/ArkType/Effect all provide schemas:</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// define your parsing functions</span>
cowSchema = z.object({
  <span class="hljs-comment">// a number that is not NaN and positive</span>
  <span class="hljs-attr">age</span>: z.number().gte(<span class="hljs-number">0</span>),
  <span class="hljs-comment">// a string name instead of Python's snake case first_name</span>
  <span class="hljs-attr">name</span>: z.string().transform( <span class="hljs-function"><span class="hljs-params">d</span> =&gt;</span> ({ …d, <span class="hljs-attr">name</span>: d.first_name }) )
})

<span class="hljs-comment">// use it to create your type</span>
type Cow = z.infer&lt;<span class="hljs-keyword">typeof</span> cowSchema&gt;

<span class="hljs-comment">// parse your data</span>
json = <span class="hljs-built_in">JSON</span>.parse(data)
cow = cowSchema.parse(json)
<span class="hljs-comment">// cow is a Cow type and safe to use!</span></code></span></pre>


<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2026/06/type-driven-development-schema.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<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>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-schema.html">Part 8 &#8211; Schema</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-total-function.html">Part 9 &#8211; Total Function</a></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 loading="lazy" 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="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="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="auto, (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>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-schema.html">Part 8 &#8211; Schema</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-total-function.html">Part 9 &#8211; Total Function</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 loading="lazy" 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="auto, (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>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-schema.html">Part 8 &#8211; Schema</a></li>



<li><a href="https://jessewarden.com/2026/06/type-driven-development-total-function.html">Part 9 &#8211; Total Function</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>
	</channel>
</rss>
