DEV Community

Cover image for Friendly TypeScript Errors: Custom Messages for Easier Debugging
nunibaranes for Really Good

Posted on • Updated on

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:

Screenshot of the default TypeScript error message showing incompatible prop types for the MyComponent component. 'is not assignable to type 'IntrinsicAttributes & Props' It highlights that 'a' is a string and 'b' is a number, causing a type mismatch.
While the information is there, it's not immediately easy to understand. 🤔

Wouldn’t it be much easier to get a clearer, more specific message, like this? 🤩

Screenshot of a TypeScript error message showing custom error handling in MyComponent. The error highlights that 'a' and 'b' must be the same type.

Now it’s clear that the props must to get the same type and why 🥳

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 InvalidRequireProps = { 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 }
Enter fullscreen mode Exit fullscreen mode

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 InvalidRequireProps
   ? "🚨 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>
}
Enter fullscreen mode Exit fullscreen mode

Now, if you try to render the component without the required props, TypeScript will provide a clear error message

TypeScript error showing that a and b props are required, with a custom error message humorously comparing the component to a bicycle with no wheels if the props are missing.

Similarly, if you pass a and b with different types, TypeScript will generate the following error:

TypeScript error showing a type mismatch between props a and b, with a custom error message stating that both props must be the same type - either both numbers for calculation or both strings for concatenation. The message humorously compares mixing types to riding a bicycle with square wheels.

👏👏👏 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!

Top comments (0)