title: How is the Maybe monad useful in TypeScript?
body: <p>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 <a href="https://engineering.dollarshaveclub.com/typescript-maybe-type-and-module-627506ecc5c8#950b" rel="nofollow noreferrer">this article about implementing your own Maybe type in TypeScript</a>:</p>
  <pre><code>enum MaybeType {
    Just = 'maybe-type__just',
    Nothing = 'maybe-type__nothing',
  }
  
  interface Just&lt;T&gt; {
    type: typeof MaybeType.Just
    value: T
  }
  
  interface Nothing {
    type: typeof MaybeType.Nothing
  }
  
  type Maybe&lt;T&gt;
    = Just&lt;T&gt;
    | Nothing
  
  const Nothing = (): Nothing =&gt; ({
    type: MaybeType.Nothing,
  })
  
  const Just = &lt;T&gt; (value: T): Just&lt;T&gt; =&gt; ({
    type: MaybeType.Just,
    value,
  })
  </code></pre>
  <p>How is this actually useful? I don’t understand how it’s any better than a type just being <code>T | undefined</code>.</p>
  <p>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 <code>undefined</code> checks littered throughout your code for having<code>Nothing</code> checks littered throughout your code?</p>
  <p>In this example, a <code>Nothing</code> result has no <code>value</code> property, but a <code>Just</code> type does. So TypeScript won’t even let me access that value without first making sure that the result is indeed a <code>Just</code>. So doesn’t that mean lots of checks everywhere? Why not just keep doing plain-old <code>undefined</code> checks? Is the example that I’m looking at just a crummy implementation of the Maybe type?</p>
  <p>Clearly I’m missing something and there’s more to it. How does this thing work and how is it useful?</p>