<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: TyIsI</title>
    <description>The latest articles on Forem by TyIsI (@tyisi).</description>
    <link>https://forem.com/tyisi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F290669%2F489a0a0e-631a-4974-8d99-42a48456e687.jpeg</url>
      <title>Forem: TyIsI</title>
      <link>https://forem.com/tyisi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tyisi"/>
    <language>en</language>
    <item>
      <title>I finally did a Typescript! Am I a real developer now?</title>
      <dc:creator>TyIsI</dc:creator>
      <pubDate>Mon, 18 Aug 2025 18:22:23 +0000</pubDate>
      <link>https://forem.com/tyisi/i-finally-did-a-typescript-am-i-a-real-developer-now-3cn6</link>
      <guid>https://forem.com/tyisi/i-finally-did-a-typescript-am-i-a-real-developer-now-3cn6</guid>
      <description>&lt;p&gt;As an AuDHD person, I've never found myself at home in classical education systems.&lt;/p&gt;

&lt;p&gt;Beyond being a perpetual weirdo and outsider, having had that foundational learning disa... different ability, I found school mostly traumatizing.&lt;/p&gt;

&lt;p&gt;From dreaming away and being distracted during class, to frustrating my algebra teacher with questions about Euler and giant primes, to the point of being thrown out of class and kindly being requested to not show up.&lt;/p&gt;

&lt;p&gt;It should be no surprise that - like a lot of others who've had the privilege growing up in the Global North - I went to work right after I graduated.&lt;/p&gt;

&lt;p&gt;I'm a hands on learner and really getting my head around Typescript has not been without its struggles.&lt;/p&gt;

&lt;p&gt;Now that I've finally having reached a level and combo of medication that's actually making a big difference, I found myself revisiting a personal project that I've been neglecting.&lt;/p&gt;

&lt;p&gt;Obviously when you open a can of worms like that, you will inevitably run into code that written in ways that one should only approach with internalized compassion and kindness.&lt;/p&gt;

&lt;p&gt;Because we live and learn. And as we learn, we develop better understanding of how things work, we adopt better, more common practices.&lt;/p&gt;

&lt;p&gt;As we learn and become better human beings, it's easy to see our past results as failure, while often we did not know better and were struggling. Regardless of whatever reasons.&lt;/p&gt;

&lt;p&gt;As I was revisiting this personal project, I found a lot of code that in hindsight should've been written completely differently. (Hindsight is 20/20 and all that.)&lt;/p&gt;

&lt;p&gt;But as a once good friend of mine once said; never be afraid to throw all your code away!&lt;/p&gt;

&lt;p&gt;It's the only way to make place for better code.&lt;/p&gt;

&lt;p&gt;So I did.&lt;/p&gt;

&lt;p&gt;I removed a lot of garbage code, switched to &lt;code&gt;vite&lt;/code&gt; with &lt;code&gt;tanstack router&lt;/code&gt; and &lt;code&gt;tailwind&lt;/code&gt;, &lt;code&gt;react-hook-form&lt;/code&gt; for forms, &lt;code&gt;swr&lt;/code&gt; for server interaction, &lt;code&gt;yoga&lt;/code&gt; + &lt;code&gt;sofa&lt;/code&gt; for the backend (bundled with &lt;code&gt;tsup&lt;/code&gt;[1]), and a multi-language monorepo[2] driven by &lt;code&gt;pnpm&lt;/code&gt;, &lt;code&gt;wireit&lt;/code&gt;, &lt;code&gt;just&lt;/code&gt;, with &lt;code&gt;prisma&lt;/code&gt; and &lt;code&gt;zod&lt;/code&gt; schemas in separate packages.&lt;/p&gt;

&lt;p&gt;But as I was cleaning up the forms and wanting to do live selective updates, I had some repeating code, which I took as a challenge to abstract/DRY into a separate function.&lt;/p&gt;

&lt;p&gt;The goal was to create a function that could take &lt;code&gt;react-hook-form&lt;/code&gt; inputs and hoist the dirty fields into the update object, before sending that off to my API.&lt;/p&gt;

&lt;p&gt;And you know how you sometimes see these gigantic strongly typed functions?&lt;/p&gt;

&lt;p&gt;Well, that happened:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hoistFields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
    &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
        &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;unknown&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;symbol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;S&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
        &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;inputObj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;outputObj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;stateObj&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;S&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;stateObj&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyName&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;inputObj&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Could not index input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stateObj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;outputObj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputObj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I feed my form type and then distill the keys to infer the dirtyFields keys as well as type the output object.&lt;/p&gt;

&lt;p&gt;Is it perfect? Definitely not.&lt;br&gt;
Can I optimize it? Definitely, and already thinking about how. (It's probably more efficient to do it in one go instead.)&lt;/p&gt;

&lt;p&gt;But it works. It's strongly typed. And last but not least, I finally feel I have a more intuitive understanding of Typescript.&lt;/p&gt;

&lt;p&gt;Next up - after fixing the frontend - is rewriting one of the components to JS/Python to Go!&lt;/p&gt;

&lt;p&gt;It's time to make some LEDs blink!&lt;/p&gt;

&lt;p&gt;Feel free to comment with questions, suggestions, or improvements!&lt;/p&gt;

&lt;p&gt;[1]: I ran into the composite bug, which I believe warrants a separate post.&lt;br&gt;
[2]: The combo of &lt;code&gt;pnpm&lt;/code&gt;, &lt;code&gt;wireit&lt;/code&gt; and &lt;code&gt;just&lt;/code&gt; is just :chefkiss:, but more about that later.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>personaldevelopment</category>
      <category>audhd</category>
      <category>neurodiversity</category>
    </item>
    <item>
      <title>Escaping from being stuck in the optimization trap</title>
      <dc:creator>TyIsI</dc:creator>
      <pubDate>Thu, 14 Mar 2024 21:01:57 +0000</pubDate>
      <link>https://forem.com/tyisi/escaping-from-being-stuck-in-the-optimization-trap-mco</link>
      <guid>https://forem.com/tyisi/escaping-from-being-stuck-in-the-optimization-trap-mco</guid>
      <description>&lt;p&gt;I've been meaning to write a post on here for a while, but we all know how it goes. Distractions, busy, other projects, not enough time.&lt;/p&gt;

&lt;p&gt;But I had an interesting epiphany the other day. One that I thought was worthwhile sharing. Because everyone has their own experiences and ways to get unstuck.&lt;/p&gt;

&lt;p&gt;As I was stuck on refactoring something and reflecting the best approach, I was thinking about it as "what is the smartest way to solve this? and more so "what exactly am I trying to solve and what is the smartest way to do this?".&lt;/p&gt;

&lt;p&gt;And that's when it struck me.&lt;/p&gt;

&lt;p&gt;Sometimes the smartest way to do a thing is to not do it in the smartest way (possible).&lt;/p&gt;

&lt;p&gt;We can always optimize the optimizations and abstract them further. But is there an actual tradeoff for doing this? Or are we simply trying to optimize it for the sake of optimizing? Are we abstracting for the right reasons or just because it's the way that we tend to do things?&lt;/p&gt;

&lt;p&gt;So for future cases, if I feel I'm stuck on a problem, I'm going to try to remember to ask myself this:&lt;/p&gt;

&lt;p&gt;Am I trying to optimize the optimization?&lt;br&gt;
(And can I settle for good/close enough?)&lt;/p&gt;

&lt;p&gt;Because sometimes two pieces of code is better than (a more complex unified) one.&lt;/p&gt;

&lt;p&gt;But I would certainly be curious to hear opinions from the community.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://unsplash.com/photos/man-wearing-white-top-using-macbook-1K9T5YiZ2WU" rel="noopener noreferrer"&gt;Image Source&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>development</category>
      <category>softwareengineering</category>
    </item>
  </channel>
</rss>
