DEV Community

Cover image for You’re a Real TypeScript Developer Only If...

You’re a Real TypeScript Developer Only If...

Hadil Ben Abdallah on June 08, 2026

A few months ago, I published You're a Real JavaScript Developer Only If... It was just a post for fun, and honestly, I didn't expect it to resona...
Collapse
 
adamthedeveloper profile image
Adam - The Developer

did a code review once, saw this guy wrote as unknown as any
lol

Collapse
 
hadil profile image
Hadil Ben Abdallah

Haha that’s one of those things that makes you pause for a solid 5 seconds 😄

as unknown as any feels like the TypeScript version of “I don’t want to think about this right now”, maximum type confusion, zero accountability 😂

Collapse
 
restofstack profile image
Mary Olowu

Am ashamed to say I have done this once. But, I did circle back at least. I was having one of those frustrating typescript type loop issues

Collapse
 
francistrdev profile image
FrancisTRᴅᴇᴠ (っ◔◡◔)っ

annnd the Saga continues! Good stuff Hadil!

Collapse
 
hadil profile image
Hadil Ben Abdallah

Haha yeah 😄 The saga definitely continues!
Thanks, Francis! Glad you enjoyed it.

Collapse
 
syedahmedx3 profile image
Syed Ahmed Mohi Uddin Hasan

TypeScript isn't trying to ruin your day. It's trying to stop future-you from ruining it. — Louder for the people in the back! 😭

My most "TypeScript developer" moment has to be writing a generic type so abstract that I needed a map and a compass to read it six months later. Awesome write-up, Hadil!

Collapse
 
hadil profile image
Hadil Ben Abdallah

This is so real 😭

That “future-you protection system” is exactly what TypeScript is doing… even if present-you doesn’t always appreciate it in the moment 😄

And honestly, that generic type situation is a rite of passage at this point. You look at it later and think: “there’s no way I wrote this”… and then you slowly realize you absolutely did 😂

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

Haha sooo real! I love this series 😂

Collapse
 
hadil profile image
Hadil Ben Abdallah

Haha thank you, Sylwia! 😄
I'm really happy you're enjoying the series!

Collapse
 
scarab-systems profile image
Scarab Systems

This is very real 😅

My most TypeScript-developer moment lately was digging into an auto-import issue where the code looked fine at the surface, but the package export boundary was not being respected the same way across paths.

That’s one of the things I appreciate about TypeScript even when it’s frustrating: the pain is usually pointing at a contract somewhere. Sometimes it’s a type contract, sometimes it’s a module boundary, sometimes it’s a package shape that the tooling has to interpret consistently.

And yes — any and // @ts-ignore are basically “I’ll deal with future-me later” buttons. Sometimes necessary, always dangerous if they become permanent furniture.

The red squiggles are annoying, but the worst bugs are the ones where the squiggles go away because we taught the repo to stop asking the question.

Collapse
 
hadil profile image
Hadil Ben Abdallah

This is so real 😄

Auto-import / export boundary issues are one of those “everything looks correct… so why is nothing correct?” moments 😂 You can stare at the code for ages and still feel like the problem is gaslighting you.

And yeah, TypeScript isn’t just complaining randomly; it’s usually pointing at some contract breaking somewhere, even if it takes a while to track down where that boundary actually is.

Collapse
 
scarab-systems profile image
Scarab Systems

Exactly 😂 That “everything is valid in isolation, but invalid once the package boundary gets involved” feeling is brutal.

That’s what makes these bugs so sneaky to me — the code is not obviously wrong, the types may not be obviously wrong, but the tooling is making an assumption about where a symbol is allowed to come from.

It’s less “TypeScript is yelling at me” and more “the repo is quietly revealing that one of its contracts is leaky.”

Collapse
 
aloisseckar profile image
Alois Sečkár • Edited

// @ts-ignore gets rejected by my ESLint rules 🥹 It enforces // @ts-expect-error <WHY?>

Collapse
 
hadil profile image
Hadil Ben Abdallah • Edited

Haha that’s actually a really solid setup 😄

Forcing a reason next to '// @ts-expect-error' is one of those "painful but good for you" rules, similar to making future-you think twice rather than simply silencing the error and moving on.

Collapse
 
itsugo profile image
Aryan Choudhary

Been a while I coded something up, kind of nostalgic but fun read!! 😆

Collapse
 
hadil profile image
Hadil Ben Abdallah

Haha I know that feeling 😄

There’s something really nostalgic about TypeScript (and coding in general); once you step away for a bit, you forget the frustration… and somehow only remember the fun parts 😂

Glad it brought back those vibes for you!

Collapse
 
klaudiagrz profile image
Klaudia Grzondziel

Ahaha, funny article and cool collab with Sylwia! 😄

Collapse
 
hadil profile image
Hadil Ben Abdallah

Haha, thank you! 😄 I'm glad you enjoyed it!

And yes, Sylwia's post was a big part of the inspiration to continue this series. I loved the idea of taking those shared developer experiences and giving them a TypeScript twist 😅

Collapse
 
klaudiagrz profile image
Klaudia Grzondziel

Would you mind if I joined you with "You’re a Real Technical Writer Only If..."? 😁

Thread Thread
 
hadil profile image
Hadil Ben Abdallah

Absolutely! 😄 That sounds like a cool idea 😍

One of the things I enjoy most about these posts is seeing people add their own version from different corners of the tech world. Developers, designers, DevOps engineers, technical writers...

"You're a Real Technical Writer Only If..." edition sounds like it could be both hilarious and painfully relatable.

So excited to read your piece and see my struggles in the list 😂

Collapse
 
wajkie profile image
Fredrik Wiking

When my strict typing resulted in a problem detection and I opened up a PR in hono/middleware

//Problem
export type OpenAPIHonoOptions<E extends Env> = {
  defaultHook?: Hook<any, E, any, any>
}

//Fix
export type OpenAPIHonoOptions<E extends Env> = {
  defaultHook?: Hook<unknown, E, string, Response | void | Promise<Response | void>>
}
Enter fullscreen mode Exit fullscreen mode

Reasoning:

  • T: unknown — defaultHook is a catch-all that applies to all routes regardless of their specific input shape. unknown is the correct type when the data type cannot be known at this level (as opposed to any, which silently opts out of type checking).

  • P: string — a route path is always a string. Using any here causes c.req and related path-typed members to resolve to any.

  • R: Response | void | Promise — these are the only meaningful return types for a hook. any allows returning anything, including values that would be silently ignored.

Collapse
 
hadil profile image
Hadil Ben Abdallah

This is the best example of “strict types feel annoying until they save the whole design” 😄

And honestly, this fix is really clean; switching from anyunknown is exactly the right move. It keeps the flexibility but forces the consumer to actually prove what they’re doing instead of bypassing the system.

I also like how you broke down the reasoning (T / P / R). That’s the part a lot of people miss when they first tighten types. It’s not about making things harder; it’s about making the boundaries explicit so nothing leaks in silently.

And yeah… any in a shared middleware API is basically an open door for accidental chaos 😅

This is the kind of small type change and big long-term safety win that makes TypeScript worth it 🙌🏻

Collapse
 
zep1997 profile image
Self-Correcting Systems

The "this should only take an hour" curse is real. I once estimated a quick type
migration before a product demo and spent the next two hours explaining to TypeScript
what I thought I meant. It was right the whole time. The worst part is knowing that and
still saying it the next time.

Collapse
 
hadil profile image
Hadil Ben Abdallah

Haha... This might be the most accurate description of the curse I've seen so far 😂

The real tragedy isn't that it happens once. It's that we all know exactly how these stories end, and yet the next time we see a "small" migration or "quick" type fix, we're right back to saying: "This should only take an hour" 😄

When it comes to estimates, developers have the shortest memory, but when it comes to humbling us with TypeScript, they have the longest memory.

Collapse
 
hemapriya_kanagala profile image
Hemapriya Kanagala

Hadil, this was a fun read. It has been so long since I used TypeScript regularly, but the "this should only take an hour" line immediately brought back memories 😄

Somehow the smallest changes always seemed to turn into a much longer debugging session than I planned for.

Collapse
 
hadil profile image
Hadil Ben Abdallah

Haha, I'm convinced that "this should only take an hour" is one of the most dangerous sentences a developer can say 😄

It always starts with so much confidence, and then somehow you're three debugging sessions deep, questioning decisions made months ago and following a trail of type errors you never expected to find 😂

I love that this line brought back memories for you. and glad you liked it 😍

Collapse
 
mark9dev profile image
Mark

I think most TypeScript developers eventually go through the same progression: first avoiding types because they feel restrictive, then gradually appreciating them after debugging a few painful runtime issues.

Collapse
 
hadil profile image
Hadil Ben Abdallah

Haha, I think that's exactly how it happens for most of us 😄
At first, TypeScript feels like that annoying friend who keeps questioning everything you're doing.
Then you spend a few hours chasing a bug that TypeScript would have caught instantly, and suddenly you're a lot more willing to listen 😂

Collapse
 
dhruvjoshi9 profile image
Dhruv Joshi

If you're relying on as any and // @ts-ignore to pass your builds, you're not actually writing TypeScript, you're just writing broken JavaScript with extra steps.

Collapse
 
hadil profile image
Hadil Ben Abdallah

Haha I get the vibe behind this 😄

But in real life projects… I think it’s a little more complicated.

Most of us don’t start with any or // @ts-ignore as a habit; they usually pop up as temporary survival tools when you’re dealing with messy legacy code, third-party libs with weak typings, or tight deadlines. It’s a bit like duct tape, not the perfect fix, but sometimes it keeps things going while you sort the real problem out properly later.

The big difference is if it stays temporary or if it becomes a habit 😅

Collapse
 
fm profile image
Fayaz

I once converted a Java project to C#, long ago.
Trust me, it was easier than converting a project from JavaScript to TypeScript. 😋

Collapse
 
hadil profile image
Hadil Ben Abdallah

Haha, I believe you! 😆

The funny thing is that when you convert Java to C#, you're mostly moving between two languages that already agree on a lot of concepts.

JavaScript → TypeScript starts with the innocent thought of "I'm just adding types".

Then TypeScript points out every assumption, edge case, nullable value, and questionable design decision that's been hiding in the codebase for years 😂

Collapse
 
aidasaid profile image
Aida Said

I had so much fun reading this 😄 I passed by almost everything in this list 😂 And like you said, I still secretly love TypeScript

Collapse
 
hadil profile image
Hadil Ben Abdallah

I'm glad you liked it 😍 We've all gone by the majority of them 😄

Collapse
 
hanadi profile image
Ben Abdallah Hanadi

Thanks for confirming I'm officially a TypeScript developer 😂

Collapse
 
hadil profile image
Hadil Ben Abdallah

Congratulations! 🎉😄

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

Nah, title is misleading: You're attempting to be... is accurate for like 60% of the cases.