Skip to content

Instantly share code, notes, and snippets.

@jsoendermann
Last active January 6, 2021 15:44
Show Gist options
  • Save jsoendermann/058d022e0b8e64980daca22bb56ae1b4 to your computer and use it in GitHub Desktop.
Save jsoendermann/058d022e0b8e64980daca22bb56ae1b4 to your computer and use it in GitHub Desktop.
TypeScript Result type
interface IValue<T> {
type: 'value'
value: T
}
interface IError<E extends Error> {
type: 'error'
error: E
}
type Result<T, E extends Error> = IValue<T> | IError<E>
class ResultClass<T, E extends Error> {
constructor(public result: Result<T, E>) { }
static value<T>(value: T): ResultClass<T, any> {
return new ResultClass({
type: 'value',
value,
})
}
static error<E extends Error>(error: E): ResultClass<any, E> {
return new ResultClass({
type: 'error',
error,
})
}
public unwrap(): T {
switch (this.result.type) {
case 'value': return this.result.value
case 'error': throw this.result.error
}
}
public map<S>(f: (T) => S): ResultClass<S, E> {
switch (this.result.type) {
case 'value':
return new ResultClass<S, E>({
type: 'value',
value: f(this.result.value),
})
case 'error': return new ResultClass<S, E>(this.result)
}
}
public valueOrDefault(d: T): T {
switch (this.result.type) {
case 'value': return this.result.value
case 'error': return d
}
}
}
function randomResult(): ResultClass<number, Error> {
if (Math.random() > 0.5) {
return ResultClass.value(42)
}
return ResultClass.error(new Error('bad luck'))
}
const r = randomResult().map(i => i + 1).valueOrDefault(77)
console.log(r)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment