🤞🤞Double Cross

The Undefined Dance: When TypeScript Can't Save You

TL;DR: Explicitly setting all properties to null defeats TypeScript's type safety and creates runtime bombs.

#typescript#null-handling#undefined#type-safety

The Code

typescript
1const spelError: ISpelError = {
2  message: null,
3  context: null,
4  contextTruncated: null,
5};
6

The Prayer 🤞🤞

"TypeScript will catch any null issues... right? And besides, I'm explicitly setting them to null, so it's intentional!"

The Reality Check

Returning an object with all properties explicitly set to null defeats the purpose of TypeScript's type safety. Accessing spelError.message.length later will throw "Cannot read property 'length' of null" at runtime. TypeScript allows this because the interface permits null values, but it creates a ticking time bomb.

The Fix

typescript
1interface ISpelError {
2  message: string;
3  context?: string;
4  contextTruncated?: string;
5}
6
7// Only create the error object when we have actual error data
8const spelError: ISpelError = {
9  message: err.name ? `${err.name}: ${err.message}` : err.toString(),
10};
11
12if (err.state?.activeContext) {
13  spelError.context = stringify(err.state.activeContext.peek());
14  spelError.contextTruncated = truncate(spelError.context, { length: 200 });
15}
16

Lesson Learned

Don't explicitly initialize optional properties to null - use optional properties (?) and only set them when you have real values.