Skip to content

Instantly share code, notes, and snippets.

@wegry
Last active July 10, 2019 13:24
Show Gist options
  • Save wegry/9bbdef11d9f24b7be87ad01fd31edc4e to your computer and use it in GitHub Desktop.
Save wegry/9bbdef11d9f24b7be87ad01fd31edc4e to your computer and use it in GitHub Desktop.
Typescript Result Types
"use strict";
// Typescript 3.5.2
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const lodash_1 = __importDefault(require("lodash"));
function Err(value) {
return {
kind: 'error',
value
};
}
function Ok(value) {
return {
kind: 'ok',
value
};
}
function map(result, f) {
if (result.kind === 'error') {
return result;
}
else {
return Ok(f(result.value));
}
}
function mapError(result, f) {
if (result.kind === 'ok') {
return result;
}
else {
return Err(f(result.value));
}
}
function unwrap(value) {
if (value.kind === 'error') {
throw new Error('Unwrap failed');
}
return value.value;
}
function unwrapError(value) {
if (value.kind === 'ok') {
throw new Error('Unwrap error failed');
}
return value.value;
}
function unwrapOr(value, or) {
if (value.kind === 'error') {
return Ok(or);
}
return value;
}
function unwrapOrDefault(value, defaultValue) {
if (value.kind === 'error') {
return defaultValue;
}
return value.value;
}
// Example calls
function wrapUnstrict(t) {
if (t === null) {
return Err(null);
}
else if (t === undefined) {
return Err(undefined);
}
return Ok(t);
}
const defaultsUnstrict = lodash_1.default.flow(wrapUnstrict, x => map(x, y => y), x => mapError(x, _ => 'Oops, error'), unwrapError, console.log);
defaultsUnstrict(undefined);
const unwrapAndLog = lodash_1.default.flow(v => unwrapOrDefault(v, 'defaulted'), console.log);
unwrapAndLog(Ok('Foo'));
unwrapAndLog(Err('Foo'));
// Typescript 3.5.2
import _ from 'lodash'
type Err<T> = {
kind: 'error'
value: T
}
type Ok<T> = {
kind: 'ok'
value: T
}
function Err<T>(value: T): Err<T> {
return {
kind: 'error',
value
}
}
function Ok<T>(value: T): Ok<T> {
return {
kind: 'ok',
value
}
}
type Result<ErrorType, OkType> = Err<ErrorType> | Ok<OkType>
function map<T, U, V>(result: Result<T, U>, f: (_: U) => V): Result<T, V> {
if (result.kind === 'error') {
return result
} else {
return Ok(f(result.value))
}
}
function mapError<T, U, V>(result: Result<T, U>, f: (_: T) => V): Result<V, U> {
if (result.kind === 'ok') {
return result
} else {
return Err(f(result.value))
}
}
function unwrap<T, U>(value: Result<T, U>) {
if (value.kind === 'error') {
throw new Error('Unwrap failed')
}
return value.value
}
function unwrapError<T, U>(value: Result<T, U>) {
if (value.kind === 'ok') {
throw new Error('Unwrap error failed')
}
return value.value
}
function unwrapOr<T, U>(value: Result<T, U>, or: U) {
if (value.kind === 'error') {
return Ok(or)
}
return value
}
function unwrapOrDefault<T, U>(value: Result<T, U>, defaultValue: U) {
if (value.kind === 'error') {
return defaultValue
}
return value.value
}
// Example calls
function wrapUnstrict<T>(t: T): Result<null | undefined, T> {
if (t === null) {
return Err(null)
} else if (t === undefined) {
return Err(undefined)
}
return Ok(t)
}
const defaultsUnstrict = _.flow(
wrapUnstrict,
x => map(x, y => y),
x => mapError(x, _ => 'Oops, error'),
unwrapError,
console.log
)
defaultsUnstrict(undefined)
const unwrapAndLog: (r: Result<string, string>) => void = _.flow(
v => unwrapOrDefault(v, 'defaulted'),
console.log
)
unwrapAndLog(Ok('Foo'))
unwrapAndLog(Err('Foo'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment