Skip to content

Instantly share code, notes, and snippets.

@bcherny
Last active February 25, 2023 23:57
Show Gist options
  • Save bcherny/615a2c2564965c1869ad8988bf5a8d50 to your computer and use it in GitHub Desktop.
Save bcherny/615a2c2564965c1869ad8988bf5a8d50 to your computer and use it in GitHub Desktop.
Options in TypeScript
type None = {
flatMap<U>(f: (value: null) => Option<U>): None
getOrElse<U>(def: U): U
isEmpty(): true
map<U>(f: (value: null) => U): None
nonEmpty(): false
orElse<U>(alternative: Option<U>): Option<U>
}
type Some<T> = {
flatMap<U>(f: (value: T) => Some<U>): Some<U>
flatMap<U>(f: (value: T) => None): None
flatMap<U>(f: (value: T) => Option<U>): Option<U>
get(): T
getOrElse<U extends T>(def: U): T | U
isEmpty(): false
map(f: (value: T) => null): None
map<U>(f: (value: T) => U): Some<U>
map<U>(f: (value: T) => U): Option<U>
nonEmpty(): true
orElse<U extends T>(alternative: Option<U>): Option<T> | Option<U>
}
type Option<T> = Some<T> | None
let None: None = {
flatMap: <T>(_f: (value: never) => Option<T>) => None,
getOrElse: <T>(def: T) => def,
isEmpty: () => true,
map: <T>(_f: (value: never) => T) => None,
nonEmpty: () => false,
orElse: <U>(alternative: Option<U>): Option<U> => alternative
}
function Some<T>(value: T): Some<T> {
return {
flatMap: <U>(f: (value: T) => Option<U>) => f(value) as any, // TODO
get: () => value,
getOrElse: <U extends T>(def: U): T | U => value || def,
isEmpty: () => false,
map: <U>(f: (value: T) => U) => Option(f(value)) as any, // TODO
nonEmpty: () => true,
orElse: <U>(_alternative: Option<U>): Option<T> | Option<U> => Some(value)
}
}
function Option<T>(value: T): Some<T>
function Option<T>(value: null): None
function Option<T>(value: T | null) {
if (value === null) {
return None
}
return Some(value)
}
let y = Option(3)
.map(() => 4)
.flatMap(() => Option(5))
.get()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment