I’m struggling to understand the value of having a Maybe type in TypeScript. I’m trying to make sense of the code example from this article about implementing your own Maybe type in TypeScript:
enum MaybeType {
Just = 'maybe-type__just',
Nothing = 'maybe-type__nothing',
}
interface Just<T> {
type: typeof MaybeType.Just
value: T
}
interface Nothing {
type: typeof MaybeType.Nothing
}
type Maybe<T>
= Just<T>
| Nothing
const Nothing = (): Nothing => ({
type: MaybeType.Nothing,
})
const Just = <T> (value: T): Just<T> => ({
type: MaybeType.Just,
value,
})
How is this actually useful? I don’t understand how it’s any better than a type just being T | undefined.
My (very limited) understanding is the Maybe type can free you from certain runtime errors and eliminate the need for null/undefined checks throughout your code. But aren’t you just trading having undefined checks littered throughout your code for havingNothing checks littered throughout your code?
In this example, a Nothing result has no value property, but a Just type does. So TypeScript won’t even let me access that value without first making sure that the result is indeed a Just. So doesn’t that mean lots of checks everywhere? Why not just keep doing plain-old undefined checks? Is the example that I’m looking at just a crummy implementation of the Maybe type?
Clearly I’m missing something and there’s more to it. How does this thing work and how is it useful?