Skip to content

Instantly share code, notes, and snippets.

@rdarder
Created December 28, 2015 19:51
Show Gist options
  • Save rdarder/0433bbd96688bdf70cd6 to your computer and use it in GitHub Desktop.
Save rdarder/0433bbd96688bdf70cd6 to your computer and use it in GitHub Desktop.
Optional<T> a la Java in typescript
///<reference path="iterator.ts"/>
///<reference path="checks.ts"/>
import AbstractIterator = Iterators.AbstractIterator;
import Iterator = Iterators.Iterator;
import checkNotNull = Preconditions.checkNotNull;
abstract class Optional<T> {
static absent<T>():Optional<T> {
return Absent.INSTANCE;
}
static of<T>(reference:T):Optional<T> {
return new Present<T>(checkNotNull(reference));
}
public static fromNullable<T>(nullableReference:T):Optional<T> {
if (nullableReference === null || nullableReference === undefined) {
return Absent.INSTANCE;
} else {
return new Present<T>(nullableReference)
}
}
abstract isPresent():boolean;
abstract get():T
abstract or(defaultValue:T):T
abstract orOptional<U extends T>(secondChoice:Optional<U>):Optional<T>
abstract orNull():T
abstract asArray():Array<T>
abstract toString()
static presentInstances<T>(optionals:Iterator<Optional<T>>):Iterator<T> {
checkNotNull(optionals);
return new SkipAbsent(optionals);
}
}
class SkipAbsent<T> extends AbstractIterator<T> {
optionals:Iterator<Optional<T>>;
constructor(optionals:Iterator<Optional<T>>) {
this.optionals = optionals;
super();
}
computeNext():T {
while (this.optionals.hasNext()) {
var optional = this.optionals.next();
if (optional.isPresent()) {
return optional.get();
}
}
return this.endOfData();
}
}
class Present<T> extends Optional<T> {
private _value:T;
constructor(value:T) {
super();
this._value = value;
}
isPresent():boolean {
return true;
}
get():T {
return this._value;
}
or(defaultValue:T):T {
return this._value;
}
orOptional<U extends T>(secondChoice:Optional<U>):Optional<T> {
return this;
}
orNull():T {
return this._value;
}
asArray():Array<T> {
return [this._value];
}
toString() {
}
}
class Absent extends Optional<any> {
isPresent():boolean {
return false;
}
get():any {
throw new Error("Optional value not present.")
}
or(defaultValue:any):any {
return defaultValue;
}
orOptional<U extends any>(secondChoice:Optional<U>):Optional<any> {
return secondChoice;
}
orNull():any {
return null;
}
asArray():Array<any> {
return [];
}
toString() {
return "Absent optional"
}
static INSTANCE:Absent = new Absent();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment