Skip to content

Instantly share code, notes, and snippets.

@znck
Created November 23, 2025 09:15
Show Gist options
  • Select an option

  • Save znck/36b61f9d4ae927e70cfe04d6e671d54a to your computer and use it in GitHub Desktop.

Select an option

Save znck/36b61f9d4ae927e70cfe04d6e671d54a to your computer and use it in GitHub Desktop.
A simple Option type
interface Protocol<T> {
orElse(defaultValue: T): T
}
interface Some<T> extends Protocol<T> {
readonly ok: true
readonly value: T
}
interface None<T> extends Protocol<T> {
readonly ok: false
}
/**
* Optional value that is either present (Some) or absent (None).
*/
export type Option<T> = Some<T> | None<T>
export const Option = Object.freeze({
some,
none,
from,
[Symbol.hasInstance](instance: unknown): instance is Option<unknown> {
return instance instanceof OptionImpl
},
})
// #region Core Factory Functions
class OptionImpl<T> implements Protocol<T> {
readonly ok: boolean
readonly value: T | undefined
constructor(ok: boolean, value?: T) {
this.ok = ok
this.value = value
}
orElse(defaultValue: T): T {
if (this.ok) {
return this.value as T
}
return defaultValue
}
}
function some<T>(value: T): Some<T> {
return new OptionImpl<T>(true, value) as Some<T>
}
let NONE_INSTANCE: None<never> | null = null
function none<T>(): None<T> {
return (NONE_INSTANCE ??= new OptionImpl<never>(false) as None<never>)
}
function from<T>(value: T | null | undefined): Option<T> {
if (value === null || value === undefined) {
return none()
}
return some(value)
}
// #endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment