<?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>Thu, 23 Jul 2026 13:42:26 +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>Flint&#8217;s Nice Interactive Linter Error</title>
		<link>https://jessewarden.com/2026/07/flints-nice-interactive-linter-error.html</link>
					<comments>https://jessewarden.com/2026/07/flints-nice-interactive-linter-error.html#respond</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Thu, 23 Jul 2026 13:42:26 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://jessewarden.com/?p=7303</guid>

					<description><![CDATA[When I teach treating errors as values, and myself wonder where an error falls on the spectrum of domain vs infra vs panic, what the user and/or developer can do about it, as a UI guy at heart, I always come back to how you display that. I wanted to cover how you&#8217;d do that [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">When I teach treating errors as values, and myself wonder where an error falls on the spectrum of domain vs infra vs panic, what the user and/or developer can do about it, as a UI guy at heart, I always come back to how you display that.</p>



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



<p class="wp-block-paragraph">I wanted to cover how you&#8217;d do that in Linting because now that LLM&#8217;s are showing us how &#8220;fuzzy things can still give definitive steps to help, with options&#8221;</p>



<p class="wp-block-paragraph">The cop-out is to be like &#8220;build it <a href="https://elm-lang.org/news/compiler-errors-for-humans">like Elm</a>&#8230; I mean Rust even copied that style so it must be good&#8221;.</p>



<p class="wp-block-paragraph">However, I&#8217;ve been reviewing JavaScript Linters lately, and the spectrum is pretty deep, but <a href="https://www.flint.fyi/">Flint</a> in particular has a nice Elm-like error in interactive mode.</p>



<p class="wp-block-paragraph">tl;dr; on Flint, it&#8217;s a hybrid JavaScript/TypeScript linter: the core and rules are written in TypeScript to make it easier to allow open source contributions, but plugins can be written in native code, like Biome/Oxlint are doing.</p>



<p class="wp-block-paragraph">Here&#8217;s a screenshot attached of Flint finding a linting failure on a loop using for, citing what file, why the linter failed for this particular bit of code, a suggestion of what to do, and a link to learn more. That&#8217;s &#8230; amazing.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="622" src="https://jessewarden.com/wp-content/uploads/2026/07/Screenshot-2026-07-23-at-9.02.17-AM-1024x622.png" alt="" class="wp-image-7304" srcset="https://jessewarden.com/wp-content/uploads/2026/07/Screenshot-2026-07-23-at-9.02.17-AM-1024x622.png 1024w, https://jessewarden.com/wp-content/uploads/2026/07/Screenshot-2026-07-23-at-9.02.17-AM-300x182.png 300w, https://jessewarden.com/wp-content/uploads/2026/07/Screenshot-2026-07-23-at-9.02.17-AM-768x466.png 768w, https://jessewarden.com/wp-content/uploads/2026/07/Screenshot-2026-07-23-at-9.02.17-AM-1536x933.png 1536w, https://jessewarden.com/wp-content/uploads/2026/07/Screenshot-2026-07-23-at-9.02.17-AM.png 1578w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Now imagine if _every_ domain and infrastructure error you created had even one tenth of this meat embedded inside it, with ability to print for non-prod/local dev logging scenarios? Always inspiring to me to see how people interpret errors, specifically linter errors which can be quite fuzzy/squishy, open to interpretation, but need some kind of actionable step to fix it. I really like <a href="https://www.flint.fyi/cli#--interactive">Flint&#8217;s approach here</a>. </p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2026/07/flints-nice-interactive-linter-error.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Positive Zod v3 vs v4 Learnings</title>
		<link>https://jessewarden.com/2026/07/positive-zod-v3-vs-v4-learnings.html</link>
					<comments>https://jessewarden.com/2026/07/positive-zod-v3-vs-v4-learnings.html#respond</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Mon, 20 Jul 2026 21:40:12 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://jessewarden.com/?p=7299</guid>

					<description><![CDATA[Side of desk project is to: Learnings the past 3 days: I really don&#8217;t like that last one. I may just not do it, install in a Zod v3 project, and &#8220;see what happens&#8221; in the unhappy paths. Once done, I can wrangle the insane grossness that is Open Feature while dual-wielding Discriminated Unions of [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Side of desk project is to:</p>



<ol class="wp-block-list">
<li>wrap native fetch with Neverthrow</li>



<li>provide nicer, Elm style return types</li>



<li>abstract away decoding/enoding for JSON</li>



<li>same, but for GraphQL + company&#8217;s rules around that</li>
</ol>



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



<p class="wp-block-paragraph">Learnings the past 3 days:</p>



<ul class="wp-block-list">
<li>Zod v3 to v4 has been a nightmare, so at first I just removed Zod and provided a decoder type interface instead b/c writing a Zod wrapper is like 1 line of code</li>



<li>&#8230; but then I found out in v3.25.0 they name spaced the versions, making it easier for each to co-exist</li>



<li>&#8230; so now I&#8217;m wondering if I should undo all my work of &#8220;abstracting away a Zod dependency</li>



<li>but then I found out many are moving to Standard Schema and it&#8217;s not a too obtuse type to include, thus enabling me to be nice to ArkType and Effect-ts peoplez</li>



<li>So now I think I can support Zod v4 internally, include an encoder interface for POST style operations, but still not exclude other schema libraries WHILE reserving the right to use Zod internally for various GraphQL schemas</li>



<li>&#8230; but still requiring me to map those ZodErrors to my own type to not &#8220;leak Zod out&#8221;.</li>
</ul>



<p class="wp-block-paragraph">I really don&#8217;t like that last one. I may just not do it, install in a Zod v3 project, and &#8220;see what happens&#8221; in the unhappy paths.</p>



<p class="wp-block-paragraph">Once done, I can wrangle the insane grossness that is Open Feature while dual-wielding Discriminated Unions of flame and frost brands.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2026/07/positive-zod-v3-vs-v4-learnings.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>24 Hours of Appalachia Race Prep</title>
		<link>https://jessewarden.com/2026/07/24-hours-of-appalachia-race-prep.html</link>
					<comments>https://jessewarden.com/2026/07/24-hours-of-appalachia-race-prep.html#respond</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Sun, 19 Jul 2026 16:29:59 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://jessewarden.com/?p=7289</guid>

					<description><![CDATA[Took the Versys-X out for a spin on the road and dirt hills. Initial scare as the grease near the place where the 2 exhaust pipes went in burned off the grease I put in there and it smoked. Then some drops from the front drain plug. I&#8217;ve learned to tell the difference between &#8220;burning [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Took the Versys-X out for a spin on the road and dirt hills.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="768" src="https://jessewarden.com/wp-content/uploads/2026/07/IMG_9027-1024x768.jpeg" alt="" class="wp-image-7290" srcset="https://jessewarden.com/wp-content/uploads/2026/07/IMG_9027-1024x768.jpeg 1024w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_9027-300x225.jpeg 300w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_9027-768x576.jpeg 768w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_9027-1536x1152.jpeg 1536w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_9027-2048x1536.jpeg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



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



<p class="wp-block-paragraph">Initial scare as the grease near the place where the 2 exhaust pipes went in burned off the grease I put in there and it smoked. Then some drops from the front drain plug. I&#8217;ve learned to tell the difference between &#8220;burning oil&#8221; smell, &#8220;burning coolant smell&#8221; and &#8220;omg I don&#8217;t know what that is burning&#8221; smell. I&#8217;m wondering if the crappy hex bolt I used didn&#8217;t have the flat head flange, thus not making a good water seal… so headed to Ace Hardware for the 20 billionth time. While scary, at least I can get parts within 15 minutes, cheap vs. online OEM which takes a week or more. Bought another one with a flat head I&#8217;ll try replacing later.</p>



<p class="wp-block-paragraph">She &#8220;felt&#8221; like she&#8217;s running better. While I still can&#8217;t tell if the $200 suspension upgrade I did improved anything.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="768" src="https://jessewarden.com/wp-content/uploads/2026/07/IMG_8966-1024x768.jpeg" alt="" class="wp-image-7293" srcset="https://jessewarden.com/wp-content/uploads/2026/07/IMG_8966-1024x768.jpeg 1024w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8966-300x225.jpeg 300w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8966-768x576.jpeg 768w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8966-1536x1152.jpeg 1536w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8966-2048x1536.jpeg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">I did replace the bushings for them which was way easier than I thought.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="768" src="https://jessewarden.com/wp-content/uploads/2026/07/IMG_8970-1024x768.jpeg" alt="" class="wp-image-7291" srcset="https://jessewarden.com/wp-content/uploads/2026/07/IMG_8970-1024x768.jpeg 1024w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8970-300x225.jpeg 300w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8970-768x576.jpeg 768w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8970-1536x1152.jpeg 1536w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8970-2048x1536.jpeg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Forks are messy af, tho; I&#8217;d say only coolant changes are messier. I could certainly tell the bike &#8220;liked&#8221; the oil change. Coolant&#8217;s hard to tell as it&#8217;s cooler today, but I know it was good for her. Cleaned the filter; it wasn&#8217;t very dirty but those &#8220;lifetime&#8221; filters need to be cleaned more often just in case, so hopefully she liked the fresh air from the box. The new rear brake lever I installed works. Friend crashed recently because of no good brakes so I tested her a few times &#8220;just in case&#8221;. (Bent because of crash at motorcross track)</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="955" src="https://jessewarden.com/wp-content/uploads/2026/07/Screenshot-2026-07-19-at-12.26.54-PM-1024x955.png" alt="" class="wp-image-7294" srcset="https://jessewarden.com/wp-content/uploads/2026/07/Screenshot-2026-07-19-at-12.26.54-PM-1024x955.png 1024w, https://jessewarden.com/wp-content/uploads/2026/07/Screenshot-2026-07-19-at-12.26.54-PM-300x280.png 300w, https://jessewarden.com/wp-content/uploads/2026/07/Screenshot-2026-07-19-at-12.26.54-PM-768x716.png 768w, https://jessewarden.com/wp-content/uploads/2026/07/Screenshot-2026-07-19-at-12.26.54-PM-1536x1432.png 1536w, https://jessewarden.com/wp-content/uploads/2026/07/Screenshot-2026-07-19-at-12.26.54-PM.png 1718w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">The tires continue to be loved in the dirt; I can just feel the 400lbs &#8220;grab&#8221; easier and make me freak out less, which in turn makes me more confident, which in turn makes the bike drive better. They say tires can&#8217;t compensate for skill, but I don&#8217;t know man…</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="768" height="1024" src="https://jessewarden.com/wp-content/uploads/2026/07/IMG_8978-768x1024.jpeg" alt="" class="wp-image-7295" srcset="https://jessewarden.com/wp-content/uploads/2026/07/IMG_8978-768x1024.jpeg 768w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8978-225x300.jpeg 225w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8978-1152x1536.jpeg 1152w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8978-1536x2048.jpeg 1536w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8978-scaled.jpeg 1920w" sizes="auto, (max-width: 768px) 100vw, 768px" /></figure>



<p class="wp-block-paragraph">The turn signals and auxiliary lights are… screwed. I keep using epoxy on top of epoxy and it just never lasts. Duct tape, while visually awful, is functionally awesome.</p>



<p class="wp-block-paragraph">Sadly, the rear sprocket didn&#8217;t fit, and just didn&#8217;t have the attention span to attempt to exchange online for whatever the right size is. However, testing her bigger, more highway focused sprocket on the motorcross track, she had torque, so… I&#8217;ll live.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="768" height="1024" src="https://jessewarden.com/wp-content/uploads/2026/07/IMG_8923-768x1024.jpeg" alt="" class="wp-image-7296" srcset="https://jessewarden.com/wp-content/uploads/2026/07/IMG_8923-768x1024.jpeg 768w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8923-225x300.jpeg 225w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8923-1152x1536.jpeg 1152w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8923-1536x2048.jpeg 1536w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_8923-scaled.jpeg 1920w" sizes="auto, (max-width: 768px) 100vw, 768px" /></figure>



<p class="wp-block-paragraph">Race is Friday. 24 hours, 500+ miles. So nervous my mechanic skills have &#8220;forgotten&#8221; something, or did something wrong I&#8217;ll later regret. Best way to learn is the hard way, no doubt, but… geez. I should have done this in my 20&#8217;s.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="768" height="1024" src="https://jessewarden.com/wp-content/uploads/2026/07/IMG_1007-768x1024.jpeg" alt="" class="wp-image-7297" srcset="https://jessewarden.com/wp-content/uploads/2026/07/IMG_1007-768x1024.jpeg 768w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_1007-225x300.jpeg 225w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_1007-1152x1536.jpeg 1152w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_1007-1536x2048.jpeg 1536w, https://jessewarden.com/wp-content/uploads/2026/07/IMG_1007-scaled.jpeg 1920w" sizes="auto, (max-width: 768px) 100vw, 768px" /></figure>



<p class="wp-block-paragraph">BTW, if you didn&#8217;t see it, here is my testing the new knobby tires on mountain, mud, and motorcross.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Testing Mitas Enduro Trail XT+ tires on a Kawasaki Versys-X 300: Mountain, Mud, Motocross Track" width="500" height="281" src="https://www.youtube.com/embed/6vdPX-8eCAc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2026/07/24-hours-of-appalachia-race-prep.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Type Driven Development: Final Thoughts</title>
		<link>https://jessewarden.com/2026/07/type-driven-development-final-thoughts.html</link>
					<comments>https://jessewarden.com/2026/07/type-driven-development-final-thoughts.html#respond</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Fri, 17 Jul 2026 14:07:01 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://jessewarden.com/?p=7247</guid>

					<description><![CDATA[Part 26 &#8211; Final Thoughts &#8211; Type Driven Development 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. There are trade offs [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Part 26 &#8211; Final Thoughts &#8211; Type Driven Development</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>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="768" src="https://jessewarden.com/wp-content/uploads/2026/07/1777493587598-1024x768.jpg" alt="" class="wp-image-7248" srcset="https://jessewarden.com/wp-content/uploads/2026/07/1777493587598-1024x768.jpg 1024w, https://jessewarden.com/wp-content/uploads/2026/07/1777493587598-300x225.jpg 300w, https://jessewarden.com/wp-content/uploads/2026/07/1777493587598-768x576.jpg 768w, https://jessewarden.com/wp-content/uploads/2026/07/1777493587598.jpg 1280w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



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



<p class="wp-block-paragraph">There are trade offs to types. More to read, comprehend, &amp; you&#8217;re often thinking in 2 modes: types + code. Watch Amanda Laucher &amp; Paul Snively from Strangeloop conference &#8220;Types vs. Tests&#8221;, you&#8217;ll how far you can push the types to the limit of your understanding. As a team, you need to decide if it&#8217;s worth getting that understanding for the benefits, or &#8220;doing something simpler for now&#8221;. No shame deciding to be pragmatic &amp; ship code. Learning types will be iterative. You/your team can gradually increase their skill, bredth of use over time, over many releases. It can also be a line in the sand for a target demographic; go read Dom Syme&#8217;s stance against Dependent Types in F#.</p>



<p class="wp-block-paragraph">Types aren&#8217;t as popular as infrastructure, IDE&#8217;s, tests, or language features. Community is a part of programming, but a small part. Historically (90&#8217;s, 2000&#8217;s), languages that had better type systems were not adopted for a variety of reasons. That has been slowly changing since the 2010&#8217;s, but super slowly. Wonderful resources online to learn w/tight communities. Despite positive impacts to design + software quality, that does not translate to job opportunities or perceived importance to engineering leadership except for rare language communities.</p>



<p class="wp-block-paragraph">Types have same issues that other programming quality initiatives have; not the norm. We&#8217;ve known for decades about positive impacts of code review, automated tests, Continous Delivery, &amp; past 10 years we now finally have mounting evidence supporting what we knew. Yet companies &amp; clients, either ignore the science, don&#8217;t know about it, or don&#8217;t know how to balance those standard quality practices w/getting actual work done. You&#8217;ll have to navigate politics, project &amp; product management, design &amp; UX, sales &amp; marketing of the techniques &amp; implementation details&#8230; WHILE doing you&#8217;re engineering job. This is especially hard w/types as they&#8217;re niche.</p>



<p class="wp-block-paragraph">Finally, code is continually created, by your team, others, &amp; library authors. Much of if not typed, or not typed to a strong degree. You&#8217;ll have to interface with this code. So learning not only &#8220;what&#8217;s good&#8221; for your domain/your code, but also &#8220;how best to safely integrate to this other code&#8221; will present additional aspects &amp; challenges.</p>



<p class="wp-block-paragraph">You&#8217;ll be confused why everyone hasn&#8217;t adopted sum types; that never goes away, a true mystery of the universe.</p>



<p class="wp-block-paragraph">I say all of this not to dissuade you, but to prepare you. Not all tradeoffs are the same; some are better than others, and types in my experience are worth it. The &#8220;hard to learn&#8221; is a great problem because this job attracts nerds &amp; we learn everyday. It can be hard and lonely, but it&#8217;s worth it.</p>



<p class="wp-block-paragraph">Card decks ordering details to follow.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2026/07/type-driven-development-final-thoughts.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Type Driven Development: How to Do It</title>
		<link>https://jessewarden.com/2026/07/type-driven-development-how-to-do-it.html</link>
					<comments>https://jessewarden.com/2026/07/type-driven-development-how-to-do-it.html#respond</comments>
		
		<dc:creator><![CDATA[JesterXL]]></dc:creator>
		<pubDate>Fri, 17 Jul 2026 14:05:11 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://jessewarden.com/?p=7240</guid>

					<description><![CDATA[Part 25 &#8211; Type Driven Development 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 Driven Development (TyDD) is a lot [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Part 25 &#8211; Type Driven Development</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><a href="https://jessewarden.com/2026/06/type-driven-development-total-function.html">Part 9 &#8211; Total Function</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-errors-as-values.html">Part 10 &#8211; Errors as Values</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-property-tests.html">Part 11 &#8211; Property Tests</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-type-proofs.html">Part 12 &#8211; Type Proofs</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-exhaustiveness-checking.html">Part 13 &#8211; Exhaustiveness Checking</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-parse-dont-validate.html">Part 14 &#8211; Parse, Don&#8217;t Validate</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-anti-corruption-layer.html">Part 15 &#8211; Anti-Corruption Layer</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-opaque-types.html">Part 16 &#8211; Opaque Types</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-maybe.html">Part 17 &#8211; Maybe</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-smart-constructors.html">Part 18 &#8211; Smart Constructors</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-pipeline.html">Part 19 &#8211; Pipeline</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-railway-oriented-programming.html">Part 20 &#8211; Railway Oriented Programming</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-typestate.html">Part 21 &#8211; Typestate</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-capabilities.html">Part 22 &#8211; Capabilities</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-immutability.html">Part 23 &#8211; Immutability</a></li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-make-impossible-states-impossible.html">Part 24 &#8211; Making Impossible States Impossible</a></li>



<li>Part 25 &#8211; Type Driven Development: How to do it</li>



<li><a href="https://jessewarden.com/2026/07/type-driven-development-final-thoughts.html">Part 26 &#8211; Final Thoughts</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="960" height="540" src="https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-toggle-1.png" alt="" class="wp-image-7242" srcset="https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-toggle-1.png 960w, https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-toggle-1-300x169.png 300w, https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-toggle-1-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></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="960" height="540" src="https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-compiler.png" alt="" class="wp-image-7243" srcset="https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-compiler.png 960w, https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-compiler-300x169.png 300w, https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-compiler-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></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="960" height="540" src="https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-comment-directive.png" alt="" class="wp-image-7244" srcset="https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-comment-directive.png 960w, https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-comment-directive-300x169.png 300w, https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-comment-directive-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></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="960" height="540" src="https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-type-proof.png" alt="" class="wp-image-7245" srcset="https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-type-proof.png 960w, https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-type-proof-300x169.png 300w, https://jessewarden.com/wp-content/uploads/2026/07/TDD-vs-TyDD-type-proof-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>
</div>
</div>



<p class="wp-block-paragraph">Type Driven Development (TyDD) is a lot like Test Driven Development (TDD); a design technique that results in proofs for easy to change code later. In most languages, you&#8217;ll use together; more types in a better type system, more tests in a bad one. Here&#8217;s 4 ways to approach it.</p>



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



<p class="wp-block-paragraph">We&#8217;ll be enforcing Secondary Accounts can only cancel their own Transactions, Primary Accounts can cancel any Transaction. I&#8217;m Primary, &amp; my daughter, Sydney, is Secondary.</p>



<p class="wp-block-paragraph">In TDD:</p>



<p class="wp-block-paragraph">1. write our expectation</p>


<pre class="wp-block-code"><span><code class="hljs language-css"><span class="hljs-selector-tag">expect</span>(
  <span class="hljs-selector-tag">canCanel</span>(
    { <span class="hljs-attribute">accountType</span>: <span class="hljs-string">'primary'</span>, id: <span class="hljs-string">'jesse'</span> },
    { <span class="hljs-attribute">transactionID</span>: <span class="hljs-string">'4'</span>, accountID: <span class="hljs-string">'jesse'</span> }
  )
)<span class="hljs-selector-class">.toBe</span>(<span class="hljs-selector-tag">true</span>)</code></span></pre>


<p class="wp-block-paragraph">2. implement the function in simplest way to make it pass</p>



<p class="wp-block-paragraph">3. refactor or move into next test</p>



<p class="wp-block-paragraph">1st: In good type systems, you just write code, fix the red, refactor. Each change that breaks the code, you let the compiler tell you what to fix. You keep the changes small.</p>



<p class="wp-block-paragraph">2nd: The <code>@ts-expect-error comment</code> directive way allows you to write types and functions normally, but for unhappy paths you must use the comment above them:</p>



<p class="wp-block-paragraph">1. create a failing type function</p>


<pre class="wp-block-code"><span><code class="hljs language-php"><span class="hljs-comment">// fixtures</span>
<span class="hljs-keyword">declare</span> <span class="hljs-keyword">const</span> jesseTransaction:
  Transaction&lt;<span class="hljs-string">'transaction-123'</span>, <span class="hljs-string">'jesse'</span>&gt;

<span class="hljs-keyword">declare</span> <span class="hljs-keyword">const</span> sydney:
  SecondaryAccount&lt;<span class="hljs-string">'sydney'</span>&gt;

<span class="hljs-comment">// @ts-expect-error Sydney must not cancel Jesse's transaction</span>
cancelPayment(jesseTransaction, sydney)</code></span></pre>


<p class="wp-block-paragraph">2. simplest function to make it pass</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// omitted input types for room</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cancelPayment</span>(<span class="hljs-params"></span>):<span class="hljs-title">CancelledTransaction</span>&lt;<span class="hljs-title">TransactionIdentity</span>&gt;
  <span class="hljs-title">return</span> </span>{
    <span class="hljs-attr">status</span>: <span class="hljs-string">'cancelled'</span>,
    <span class="hljs-attr">transactionID</span>: transaction.id,
  }
}</code></span></pre>


<p class="wp-block-paragraph">3. Now your <code>@ts-expect-error</code> comment will no longer be underlined red. Refactor types OR do happy paths without the comment (e.g. <code>cancelPayment(jesseTransaction, jesse)</code> )</p>



<p class="wp-block-paragraph"><strong>Caveat</strong>: The comment must be above compiler error; if you multi-line your types like me, you may have to move it.</p>



<p class="wp-block-paragraph">3rd: The type proof way is similiar:</p>



<p class="wp-block-paragraph">1. write a failing proof</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// fixtures</span>
type JesseTransaction = Transaction&lt;<span class="hljs-string">'1'</span>, <span class="hljs-string">'jesse'</span>&gt;
type Primary = PrimaryAccount&lt;<span class="hljs-string">'jesse'</span>&gt;

<span class="hljs-comment">// function</span>
type CanCancel&lt;_Account, _Transaction,&gt; = <span class="hljs-literal">false</span>

<span class="hljs-comment">// failing proof</span>
type _sydneyCantCancelJesseTransaction = Assert&lt;
  CanCancel&lt;
    MainPrimary, AliceTransaction
  &gt;
&gt;</code></span></pre>


<p class="wp-block-paragraph">2. make <code>CanCancel</code> pass by improving the type</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// excluded TransactionOwner for space</span>
type CanCancel&lt; CandidateAccount, CandidateTransaction, &gt; =
  CandidateAccount extends PrimaryAccount&lt;string&gt; ? <span class="hljs-literal">true</span> :
    CandidateAccount extends SecondaryAccount&lt; infer AccountIdentity &gt; ?
      Equal&lt; AccountIdentity, TransactionOwner&lt;CandidateTransaction&gt; &gt; : <span class="hljs-literal">false</span></code></span></pre>


<p class="wp-block-paragraph">3. either refactor or move to additional proof tests</p>



<p class="wp-block-paragraph">The fourth is just to intermingle 1 of the above 3 _while_ you do TDD. That&#8217;s what I do.</p>



<p class="wp-block-paragraph">Part 26 will have final conclusions.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jessewarden.com/2026/07/type-driven-development-how-to-do-it.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
