144: Gary Bernhardt - TypeScript and Testing
Episode
84 min
Read time
2 min
Topics
Software Development, Product & Tech Trends, Crypto & Web3
AI-Generated Summary
Key Takeaways
- ✓Test reduction through types: TypeScript enables a 4:1 production-to-test code ratio compared to typical 1:2 ratios in dynamic languages. The entire React frontend has zero component tests, relying instead on type checking and minimal Cypress smoke tests covering all lessons.
- ✓Runtime validation with IOTs: IOTs library solves TypeScript's type erasure problem by defining schemas that generate both runtime validation and static types from a single definition. This allows untrusted API request data to safely enter the typed system without manual synchronization between validators and types.
- ✓Conditional code placement: Push conditional logic deeper into system layers rather than at API endpoints or controllers. Testing database models directly requires no HTTP request setup and runs orders of magnitude faster, while TypeScript guarantees the wiring between layers works correctly without explicit tests.
- ✓Discriminated unions for state: Use literal types with a "kind" property to model exclusive states. Execute Program defines five user subscription states as literal string unions, ensuring every switch statement handles all cases. Adding a sixth state triggers compile errors at every location requiring updates.
- ✓Structural typing flexibility: TypeScript's structural type system allows union types to combine existing types without modifying source code or introducing artificial base classes. Functions accepting "user or group" unions can be created without touching either original type definition, containing complexity within the function itself.
What It Covers
Gary Bernhardt explains why he rebuilt Execute Program as a full-stack TypeScript application, detailing how static typing reduces test requirements by 80% while maintaining code quality through strategic testing of core logic layers.
Key Questions Answered
- •Test reduction through types: TypeScript enables a 4:1 production-to-test code ratio compared to typical 1:2 ratios in dynamic languages. The entire React frontend has zero component tests, relying instead on type checking and minimal Cypress smoke tests covering all lessons.
- •Runtime validation with IOTs: IOTs library solves TypeScript's type erasure problem by defining schemas that generate both runtime validation and static types from a single definition. This allows untrusted API request data to safely enter the typed system without manual synchronization between validators and types.
- •Conditional code placement: Push conditional logic deeper into system layers rather than at API endpoints or controllers. Testing database models directly requires no HTTP request setup and runs orders of magnitude faster, while TypeScript guarantees the wiring between layers works correctly without explicit tests.
- •Discriminated unions for state: Use literal types with a "kind" property to model exclusive states. Execute Program defines five user subscription states as literal string unions, ensuring every switch statement handles all cases. Adding a sixth state triggers compile errors at every location requiring updates.
- •Structural typing flexibility: TypeScript's structural type system allows union types to combine existing types without modifying source code or introducing artificial base classes. Functions accepting "user or group" unions can be created without touching either original type definition, containing complexity within the function itself.
Notable Moment
Bernhardt reveals that changing a database column type automatically cascades through the entire stack via TypeScript errors, guiding developers from database layer through API handlers to React components. This eliminates the forgotten edge cases that tests cannot anticipate, catching issues no test suite would find.
Episode Transcript
In this episode of Fullstack Radio, I talked to Gary Bernhardt about building execute program as a full stack TypeScript application and the implications using TypeScript has on what you need to test. This is Fullstack Radio episode one forty four. Hey, everyone. Welcome to another episode of the Fullstack Radio podcast. I'm your host, Adam Whelan. And today, it's my pleasure to welcome to the show, Gary Bernhardt, who I've been a massive fan of since I basically first became a professional programmer way back in, like, 2012. So it's super awesome to have you on the show, Gary. How's it going, man? It's going well, and thank you for having me. And I you had never told me that, so I'm very flattered. Yeah. Yeah. I was, like, a huge, like, Destroy All Software fan from, like, back in the you know, in my early days of learning, to program. And I think still to this day, like, I haven't seen, like, an educational resource that really, like, resonated with what the stuff that I wanted to learn as as much as Destroy All Software did. So, I actually remember seeing you speak at CodeMash, and, I was, like, too nervous to even, like, introduce myself because I was, like, such a fanboy at the time in my my early junior days of programming. So, yeah, it's awesome to have a chance to chat with with you here. Yeah. Well, yeah, I appreciate it. So where do you wanna start? Yeah. So I think what I wanna talk about today is I mean, what originally got me excited to talk to you in terms of topics is you recently I don't know if recently is really the right word anymore, but something that you're currently kind of your active project is execute program, which is like an online, tool to help people, like, learn different programming topics with all this, like, crazy innovative, like, interactive learning tech that you've sort of, like, built to make this experience sort of really unique and and work better than a lot of the ways that people have historically tried to learn these sorts of topics. And while you've been doing that, occasionally, you'll tweet out, like, pretty interesting little tidbits around how you've been, like, sort of putting it together. And the thing that sort of got it on my radar originally was just realizing that you were building this whole thing as, like, a full stack JavaScript application or TypeScript application, I think. Right? Yeah. And, until then, I knew you as, like, the Ruby and Python guy. You know what I mean? And Mhmm. With Bash and all and Vim and, you know, all this other stuff. But definitely not known for, like, in in the in the sort of JavaScript world. So it got me kinda interested because I was thinking, well, okay. Well, why is Gary, like, going full, JavaScript? He's, like, building stuff with Node and …
Get the full transcript (16,775 words) + summary by email — free
One-time email with the complete transcript and AI summary of this episode. No account needed.
One email, no spam. We’ll also show you what SignalCast does.
You just read a 3-minute summary of a 81-minute episode.
Get Full Stack Radio summarized like this every Monday — plus up to 2 more podcasts, free.
Pick Your Podcasts — FreeKeep Reading
More from Full Stack Radio
153: DHH – Omarchy and Designing Your Own OS on Arch Linux
Aug 21 · 76 min
Beyond Biotech
How Eli Lilly's biotech collaboration model is rewriting early-stage innovation
Feb 6
More from Full Stack Radio
152: Ben Orenstein - How to Stand Out When Applying for a Job at a Small Company
Jan 28 · 47 min
Lenny's Podcast
Why LinkedIn is turning PMs into AI-powered "full stack builders” | Tomer Cohen (LinkedIn CPO)
Dec 4
Books, tools, and gear mentioned in this episode
SignalCast may earn commission on purchases via these links.
Tools
- IOTsRecommended
“IOTs library solves TypeScript's type erasure problem by defining schemas that generate both runtime validation and static types from a single definition.”
“The entire React frontend has zero component tests, relying instead on type checking and minimal Cypress smoke tests covering all lessons.”
- CypressRecommended
“The entire React frontend has zero component tests, relying instead on type checking and minimal Cypress smoke tests covering all lessons.”
- TypeScriptRecommended
“Gary Bernhardt explains why he rebuilt Execute Program as a full-stack TypeScript application, detailing how static typing reduces test requirements by 80% while maintaining code quality through strategic testing of core logic layers.”
More from Full Stack Radio
We summarize every new episode. Want them in your inbox?
153: DHH – Omarchy and Designing Your Own OS on Arch Linux
152: Ben Orenstein - How to Stand Out When Applying for a Job at a Small Company
151: DHH – Building HEY with Hotwire
150: Secret Screencasting Tips & Behind the Scenes of Tailwind CSS 2.0
149: Choosing a Payment Processor, Radical Icons & W3C Hype
Similar Episodes
Related episodes from other podcasts
Beyond Biotech
Feb 6
How Eli Lilly's biotech collaboration model is rewriting early-stage innovation
Lenny's Podcast
Dec 4
Why LinkedIn is turning PMs into AI-powered "full stack builders” | Tomer Cohen (LinkedIn CPO)
Odd Lots
Jun 29
Baidu's CFO on How It Became a Full-Stack AI Player
a16z Podcast
Apr 17
The System Behind Self-Driving: Waymo’s Dmitri Dolgov
My First Million
Nov 14
How Alex Hormozi Gets Other People To Build His $100M+ Empire
Explore Related Topics
This podcast is featured in Best Cybersecurity Podcasts (2026) — ranked and reviewed with AI summaries.
Read this week's Software Engineering Podcast Insights — cross-podcast analysis updated weekly.
You're clearly into Full Stack Radio.
Every Monday, we deliver AI summaries of the latest episodes from Full Stack Radio and 192+ other podcasts. Free for one show.
Start My Monday DigestNo credit card · Unsubscribe anytime