Maybe a type in typescript Maybe a type in typescript typescript typescript

Maybe a type in typescript


Depending on the case, it can be void, undefined, or ? optional modifier for properties and parameters.

It's:

function foo(x : string) : number | void {    // returns nothing}

void and undefined types are compatible, but there is some difference between them. The former is preferable for function return types, because the latter requires a function to have return statement:

function foo(x : string) : number | undefined {    return;}

Maybe can be implemented with generic type. Explicit Nothing type can be implemented with unique symbol:

const Nothing = Symbol('nothing');type Nothing = typeof Nothing;type Maybe<T> = T | Nothing;function foo(x : string) : Maybe<number> {    return Nothing;}

Or a class (private fields can be used to prevent ducktyping):

abstract class Nothing {    private tag = 'nothing'}type Maybe<T> = T | typeof Nothing;function foo(x : string) : Maybe<number> {    return Nothing;}

Notice that class types designate class instance type and require to use typeof when a class is referred.

Or an object (if duck typing can be desirable):

const Nothing: { tag: 'Nothing' } = { tag: 'Nothing' };type Nothing = typeof Nothing;type Maybe<T> = T | Nothing;function foo(x : string) : Maybe<number> {    return Nothing;}


enum Nothing {  Nothing = 'Nothing'}type Maybe<A> = A | Nothingtype MaybeNumber = Maybe<number>const isNothing = (m: MaybeNumber): m is Nothing => m === Nothing.Nothing const foo = (m: MaybeNumber) => {  if (isNothing(m)) {    return Nothing.Nothing  } else {    return m + 1  }}foo(1) // ✔️foo('Nothing') // ❌foo(Nothing.Nothing) // ✔️

or without using an enum using a string literal type

const Nothing = '__nothing__'type Maybe<A> = A | Nothingtype MaybeNumber = Maybe<number>const isNothing = (m: MaybeNumber): m is Nothing => m === Nothing const foo = (m: MaybeNumber) => {  if (isNothing(m)) {    return Nothing  } else {    return m + 1  }}foo(1) // ✔️foo(Nothing) // ✔️foo('__nothing__') // ✔️

or with symbols

const nothing = Symbol('Nothing')type Nothing = typeof nothingtype Maybe<A> = A | Nothingtype MaybeNumber = Maybe<number>const isNothing = (m: MaybeNumber): m is Nothing => m.toString() === 'Symbol(Nothing)' const foo = (m: MaybeNumber) => {  if (isNothing(m)) {    return nothing  } else {    return m + 1  }}foo(1) // ✔️foo(nothing) // ✔️

live on stackblitz