-
-
Save piotrgrundas/8f7f2a38e9721353d1c06fc3a2ccdac4 to your computer and use it in GitHub Desktop.
typescript / javascript version of Optional
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Function<T, R> = (value: T) => R; | |
type Supplier<T> = () => T; | |
type Consumer<T> = (value: T) => void; | |
export interface OptionalMonad<T> { | |
filter: (predicate: (value?: T) => boolean) => OptionalMonad<T>; | |
ifPresent: (consumer: (value?: T) => void) => void; | |
isPresent: () => boolean; | |
map: <R>(mapper: (value?: T) => R) => OptionalMonad<R>; | |
flatMap: <R>(mapper: (value?: T) => OptionalMonad<R>) => OptionalMonad<R>; | |
orElse: (value: T) => T; | |
orElseGet: (supplier: () => T) => T; | |
get: () => T; | |
} | |
interface Optional { | |
<T>(value?: T): OptionalMonad<T>; | |
of<T>(value: T): OptionalMonad<T>; | |
ofNullable<T>(value?: T): OptionalMonad<T>; | |
empty(): OptionalMonad<any>; | |
} | |
const OptionalCreator = <T>(value?: T): OptionalMonad<T> => { | |
const isPresent = typeof value !== 'undefined' && value !== null; | |
return { | |
filter: (predicate: (value?: T) => boolean): OptionalMonad<T> => { | |
return predicate(value) ? OptionalCreator(value) : OptionalCreator(); | |
}, | |
ifPresent: (consumer: Consumer<T>): void => { | |
consumer(value); | |
}, | |
isPresent: (): boolean => isPresent, | |
map: <R>(mapper: Function<T, R>): OptionalMonad<R> => { | |
if (isPresent) { | |
return OptionalCreator(mapper(value)); | |
} | |
return OptionalCreator(); | |
}, | |
flatMap: <R>(mapper: Function<T, OptionalMonad<R>>): OptionalMonad<R> => { | |
if (isPresent) { | |
return mapper(value); | |
} | |
return OptionalCreator(); | |
}, | |
orElse: (elseValue: T) => (isPresent ? value : elseValue), | |
orElseGet: (supplier: Supplier<T>) => (isPresent ? value : supplier()), | |
get: () => value, | |
}; | |
}; | |
const Optional = (<T>(value?: T) => OptionalCreator(value)) as Optional; | |
Optional.ofNullable = (<T>(value?: T) => OptionalCreator(value)) as Optional; | |
Optional.of = (<T>(value: T) => { | |
if (typeof value === 'undefined' || value === null) { | |
throw new Error('Optional value cannot be null/undefined'); | |
} | |
return OptionalCreator(value); | |
}) as Optional; | |
Optional.empty = () => OptionalCreator(); | |
export { Optional }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment