Skip to content

Instantly share code, notes, and snippets.

@WouterSpaak
Last active May 7, 2019 07:31
Show Gist options
  • Save WouterSpaak/0103645b1b5aed102701353b553996c5 to your computer and use it in GitHub Desktop.
Save WouterSpaak/0103645b1b5aed102701353b553996c5 to your computer and use it in GitHub Desktop.
type Nil = null | undefined;
class Maybe<T> {
private wrappedValue: T | Nil;
constructor(value: T | Nil) {
this.wrappedValue = value;
}
map<U>(fn: (value: T) => U): Maybe<U> {
if (!this.wrappedValue) {
return this as Maybe<any>;
}
return new Maybe(fn(this.wrappedValue));
}
flatMap<U>(fn: (value: T) => Maybe<U>): Maybe<U> {
if (!this.wrappedValue) {
return this as Maybe<any>;
}
return fn(this.wrappedValue);
}
get<K extends keyof T>(key: K): Maybe<T[K]> {
return this.map(value => value[key]);
}
valueOrDefault(defaultValue: T | Nil): T {
return this.wrappedValue ? this.wrappedValue : defaultValue;
}
}
interface Person {
name: string;
town: {
city: {
country: string;
}
}
}
const alice: Person = {
name: 'Alice',
town: {
city: {
country: 'AliceCountry'
}
}
};
const bob: any = {
name: 'Bob'
};
const maybeAlice = new Maybe(alice);
const aliceCountry = maybeAlice.get('town').get('city').get('country').valueOrDefault('default value');
console.log(aliceCountry); // <= logs 'AliceCountry'
const maybeBob = new Maybe<Person>(bob);
const bobCountry = maybeBob.get('town').get('city').get('country').valueOrDefault('default value');
console.log(bobCountry); // <= logs 'default value'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment