Friendly TypeScript Errors: Custom Messages for Easier Debugging
Ever struggled with cryptic TypeScript errors that slow down your debugging process? In large projects, unclear error messages can turn simple bugs into major roadblocks.
Take, for example, a common TypeScript error when props don’t match the expected types. Here’s how TypeScript usually presents these errors:
Wouldn’t it be much easier to get a clearer, more specific message, like this? 🤩
In large projects, customizing TypeScript errors makes debugging faster and more intuitive.
In this article, I’ll show you how to customize TypeScript’s error messages to make them clearer and more helpful for developers.
We’ll use type guards and generic types to create developer-friendly errors that make your code safer and easier to maintain.
Let’s dive into making your error messages both functional and easy to understand.
Making Error Messages More Developer-Friendly
We’ll use generic types and type guards to create custom TypeScript errors in our code:
Step 1: Define Expected and Invalid Types
First, define the expected and invalid prop types to trigger TypeScript errors:
// Define the base props type where both `a` and `b` can be either a number or a string.
type Props = { a?: string | number; b?: string | number };
// Define the invalid props type when either `a` or `b` is not provided.
type InvalidRequiredProps = { a?: never } | { b?: never };
// Define the invalid props type when `a` and `b` have different types.
type InvalidTypeProps = { a: number; b: string } | { a: string; b: number }
Step 2: Enforce Strict Type Compatibility
Next, we’ll create a generic React component that enforces strict type compatibility between the two props using generic type:
// Ensure a and b are provided and have the same type.
type TypeGuardValidateProps<T extends Props> =
T extends InvalidRequiredProps
? "🚨 MyComponent's Props `a` and `b` are required 🤦🏻♀️ - without them, this component is as useful as a bicycle with no wheels! 😝"
: T extends InvalidTypeProps
? "🚨 MyComponent's Props `a` and `b` must to get the same type 🙏🏼 - either both numbers for calculation or both strings for concatenation. Mixing them? That’s like trying to ride a bicycle with square wheels! 😜"
: T;
// Define a generic React component that applies type validation.
function MyComponent<T extends Props>(props: TypeGuardValidateProps<T>){
const {a, b} = props as T;
return <div>{a + b}</div>
}
Now, if you try to render the component without the required props, TypeScript will provide a clear error message
Similarly, if you pass a and b with different types, TypeScript will generate the following error:
👏👏👏 Conclusion
We explored custom TypeScript error messages. You can extend this approach to handle more cases, making your code clearer, readable, and safer.
In a recent project, design limitations required type guards to block certain options, but it wasn’t clear why. This led me to create custom TypeScript error messages for clearer feedback.
These custom error messages not only help individual developers debug faster but can also be invaluable for larger teams where clear communication through errors prevents misunderstandings.
Here’s my CodeSandbox with examples, showcasing custom error messages and a forwardRef workaround to address type loss in forwarded ref components.
Mastering these techniques will make your React components more robust and developer-friendly.
Try implementing these techniques in your own projects and let me know how it improves your debugging process! 💪 Good luck!