Full-time TypeScript educator. Ex-@vercel, @statelyai. Used to be a voice coach. He/him. Author of Total TypeScript 🧙 Hire me to teach your team TypeScript!
5 subscribers
Oct 1 • 7 tweets • 2 min read
z.strict() fixed a nasty bug for me this morning.
You should probably be using it on most of the schemas that handle outside data.
Here's the bug 🧵
I had a form where I was marking the date a post was posted. I was expecting a key of `postedAt`, with an optional datetime.
Aug 20 • 13 tweets • 3 min read
Narrowing down the types of values is key knowledge for any TypeScript dev.
Here's 11 different ways you can do it. I bet you won't know 2 or 3 of them!
🧵
Narrowing with typeof:
Aug 8 • 10 tweets • 3 min read
So many folks don't know about structuredClone.
It's awesome, built-in, and supported in all major browsers.
Let's learn 🧵
A common pattern in JavaScript is to create an immutable clone of an object. This is useful when you want to make mutations to it without changing the original.
For that, you'll often see code using the spread operator: `{ ...obj }`.
Aug 7 • 4 tweets • 1 min read
I'm starting to think that library types in TypeScript are all wrong.
Instead of top-level types, they should be available right on the functions that use them.
Brief thread 🧵
How is this possible? Well, it's due to a trick in the way namespaces work in TypeScript.
When you export a namespace with the same name as a function, TypeScript combines the two:
Aug 5 • 11 tweets • 4 min read
I've changed my mind on .d.ts files.
If you're writing application code, you should NEVER use them.
Let me explain 🧵
Declaration files are files that only contain types.
They've got two purposes - providing types for JavaScript files, and augmenting types in the global scope.
After all the chat about typing event handlers in React, I figured I'd write down all the suggestions folks gave.
Quick 🧵
The most popular solution is to hover the onChange attribute in the JSX, then use that to type your handler.
But this creates an astonishingly long type - very intimidating for newbies.
Sep 4, 2023 • 4 tweets • 2 min read
How should you type React Props?
You've got three options. type, interface or an inline object literal.
Inline object literals might be fast to write, but it means you can't extract the type out for use elsewhere in your codebase:
This makes them hard to recommend.
So, interface vs type again. As I've said before, I prefer type.
But let's say you're building an input that needs to take all the props of 'input', but with an extra label.
For those cases, you must use interfaces:
Using an intersection here will slow down TypeScript on the scale of a large codebase. interface extends is the way to go.
This means that it's a good idea to get into the habit of using interfaces for each prop declaration.
I recommend using a code snippet to declare the interface for you:
All the speed of an object literal, but all the reusability and TS performance of an interface.
Want to share outside of X? Head to Total TypeScript:
Anyone know if it's possible to detect a QR code (or even just a fiducial) from a video using ffmpeg?
I'm asking for a slightly hilarious reason.
I use ffmpeg for automatically editing my videos. When I screw up a take, I want to be able to hold up a QR code on a paddle to tell my editing software to discard that take.
Mar 6, 2023 • 20 tweets • 7 min read
Why any's happen, how to stop them, and why unknown isn't necessarily a better solution 🧵
Any 'any' in a codebase is a cause for concern. That's because it disables typechecking on the thing it's assigned to.
Pass it to a function parameter? You then can't guarantee anything about that function parameter.
Mar 3, 2023 • 5 tweets • 2 min read
Working with mocks in TS sucks.
The only way you can make it work is by slapping 'as' on everything - which can make the tests hard to maintain.
What if you had a simple set of functions that could let you pass whatever you wanted, but with perfect autocomplete?
This feels pretty simple on the surface - many of you might have tried to make these kinds of abstractions before.
But it's harder than you think - you need a bit of wizardry. Let's take partial().
Why isn't the code below working?
Mar 2, 2023 • 18 tweets • 6 min read
satisfies in TypeScript has been out for a little while now.
Overall, it's been a success - but it's starting to cause some confusion.
Let's clear it up.
satisfies has added yet another tool to the TypeScript user's toolkit.
There are now _three_ ways to assign types to values.
Total TypeScript is ready.
🧙 Hundreds of videos over three modules
🔥 The deepest exploration of Generics on the market
❤️ Interactive editors, transcripts, and thousands of words of accompanying articles
🪄 Perfect if you've used TS for a while, but want to achieve mastery
Here, there were some globals being stored for safekeeping in the global scope.
I added their types using a declare global, meaning they could be safely accessed (and spotted a subtle bug in the process).
Feb 15, 2023 • 24 tweets • 7 min read
If you don't know generics, I promise you'll understand them by the end of this thread.
I like a challenge.
What you might think of as generics in TypeScript is actually three separate concepts:
- Passing types to types
- Passing types to functions
- Inferring types from arguments passed to functions
Feb 13, 2023 • 13 tweets • 4 min read
Let's talk about branded types.
If I were building an app where security was critical, I'd use the crap out of them.
A Brand type lets you use a bit of 'nominal' typing inside TypeScript.
By declaring a unique symbol, 'brand', we can use this Brand type helper to create types with 'names'.