This content originally appeared on DEV Community and was authored by TyIsI
As an AuDHD person, I've never found myself at home in classical education systems.
Beyond being a perpetual weirdo and outsider, having had that foundational learning disa... different ability, I found school mostly traumatizing.
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.
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.
I'm a hands on learner and really getting my head around Typescript has not been without its struggles.
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.
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.
Because we live and learn. And as we learn, we develop better understanding of how things work, we adopt better, more common practices.
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.
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.)
But as a once good friend of mine once said; never be afraid to throw all your code away!
It's the only way to make place for better code.
So I did.
I removed a lot of garbage code, switched to vite
with tanstack router
and tailwind
, react-hook-form
for forms, swr
for server interaction, yoga
+ sofa
for the backend (bundled with tsup
[1]), and a multi-language monorepo[2] driven by pnpm
, wireit
, just
, with prisma
and zod
schemas in separate packages.
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.
The goal was to create a function that could take react-hook-form
inputs and hoist the dirty fields into the update object, before sending that off to my API.
And you know how you sometimes see these gigantic strongly typed functions?
Well, that happened:
export const hoistFields = <
T extends Record<string | number | symbol, unknown> = Record<
string | number | symbol,
unknown
>,
K extends string | number | symbol = keyof T,
S extends Partial<Record<K, boolean | undefined>> = Partial<
Record<K, boolean | undefined>
>
>(
keyName: keyof S,
inputObj: T,
outputObj: Partial<T>,
stateObj?: S
): void => {
if (typeof stateObj === 'undefined') return
if (!(keyName in inputObj)) throw new Error('Could not index input')
if (stateObj[keyName] === true) outputObj[keyName] = inputObj[keyName]
}
I feed my form type and then distill the keys to infer the dirtyFields keys as well as type the output object.
Is it perfect? Definitely not.
Can I optimize it? Definitely, and already thinking about how. (It's probably more efficient to do it in one go instead.)
But it works. It's strongly typed. And last but not least, I finally feel I have a more intuitive understanding of Typescript.
Next up - after fixing the frontend - is rewriting one of the components to JS/Python to Go!
It's time to make some LEDs blink!
Feel free to comment with questions, suggestions, or improvements!
[1]: I ran into the composite bug, which I believe warrants a separate post.
[2]: The combo of pnpm
, wireit
and just
is just :chefkiss:, but more about that later.
This content originally appeared on DEV Community and was authored by TyIsI

TyIsI | Sciencx (2025-08-18T18:22:23+00:00) I finally did a Typescript! Am I a real developer now?. Retrieved from https://www.scien.cx/2025/08/18/i-finally-did-a-typescript-am-i-a-real-developer-now/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.