Skip to content

Instantly share code, notes, and snippets.

@HamedFathi
Forked from bcherny/options-in-typescript.ts
Created February 18, 2023 10:20
Show Gist options
  • Select an option

  • Save HamedFathi/30482cf9f324967b51da9f5913d491c2 to your computer and use it in GitHub Desktop.

Select an option

Save HamedFathi/30482cf9f324967b51da9f5913d491c2 to your computer and use it in GitHub Desktop.

Revisions

  1. @bcherny bcherny revised this gist Jul 6, 2017. 1 changed file with 12 additions and 31 deletions.
    43 changes: 12 additions & 31 deletions options-in-typescript.ts
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,8 @@
    type None = {
    flatMap<U>(f: (value: never) => Option<U>): None
    flatMap<U>(f: (value: null) => Option<U>): None
    getOrElse<U>(def: U): U
    isEmpty(): true
    map<U>(f: (value: never) => U): None
    map<U>(f: (value: null) => U): None
    nonEmpty(): false
    orElse<U>(alternative: Option<U>): Option<U>
    }
    @@ -14,7 +14,8 @@ type Some<T> = {
    get(): T
    getOrElse<U extends T>(def: U): T | U
    isEmpty(): false
    map<U>(f: (value: T) => null): None
    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>
    @@ -33,46 +34,26 @@ let None: None = {

    function Some<T>(value: T): Some<T> {
    return {
    flatMap: <U>(f: (value: T) => Option<U>): Option<U> => {
    if (value) {
    let newValue = f(value)
    if (newValue === null) {
    return None
    }
    return newValue
    } else {
    return None
    }
    },
    flatMap: <U>(f: (value: T) => Option<U>) => f(value) as any, // TODO
    get: () => value,
    getOrElse<U extends T>(def: U): T | U {
    return value || def
    },
    getOrElse: <U extends T>(def: U): T | U => value || def,
    isEmpty: () => false,
    map: <U>(f: (value: T) => U): Option<U> => {
    if (value) {
    let newValue = f(value)
    if (newValue === null) {
    return None
    }
    return Some(newValue)
    } else {
    return None
    }
    },
    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): Option<T> {
    function Option<T>(value: T | null) {
    if (value === null) {
    return None
    }
    return Some(value)
    }

    let x = Option(3)
    let y = x.map(() => 4).flatMap(() => Option(5))
    let y = Option(3)
    .map(() => 4)
    .flatMap(() => Option(5))
    .get()
  2. @bcherny bcherny created this gist Jul 6, 2017.
    78 changes: 78 additions & 0 deletions options-in-typescript.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,78 @@
    type None = {
    flatMap<U>(f: (value: never) => Option<U>): None
    getOrElse<U>(def: U): U
    isEmpty(): true
    map<U>(f: (value: never) => 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<U>(f: (value: T) => null): None
    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>): Option<U> => {
    if (value) {
    let newValue = f(value)
    if (newValue === null) {
    return None
    }
    return newValue
    } else {
    return None
    }
    },
    get: () => value,
    getOrElse<U extends T>(def: U): T | U {
    return value || def
    },
    isEmpty: () => false,
    map: <U>(f: (value: T) => U): Option<U> => {
    if (value) {
    let newValue = f(value)
    if (newValue === null) {
    return None
    }
    return Some(newValue)
    } else {
    return None
    }
    },
    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): Option<T> {
    if (value === null) {
    return None
    }
    return Some(value)
    }

    let x = Option(3)
    let y = x.map(() => 4).flatMap(() => Option(5))