Skip to content

Instantly share code, notes, and snippets.

@mvf4z7
Last active November 11, 2020 18:12
Show Gist options
  • Save mvf4z7/5879f4d7e2956328bf6038f26b8520f5 to your computer and use it in GitHub Desktop.
Save mvf4z7/5879f4d7e2956328bf6038f26b8520f5 to your computer and use it in GitHub Desktop.
TypeScript Result type
type Ok<T> = {
type: 'Ok';
value: T;
};
type Err<T> = {
type: 'Err';
value: T;
};
type Result<T, E> = Ok<T> | Err<E>;
export function ok<T>(value: T): Ok<T> {
return {
type: 'Ok',
value,
};
}
export function error<E>(error: E): Err<E> {
return {
type: 'Err',
value: error,
};
}
export function isOk<T, E>(result: Result<T, E>): result is Ok<T> {
return result.type === 'Ok';
}
export function isError<T, E>(result: Result<T, E>): result is Err<E> {
return result.type === 'Err';
}
export function unwrap<T, E>(result: Result<T, E>): T {
if (isError(result)) {
throw new Error(`Attempt to unwrap an error with value: ${result.value}`);
}
return result.value;
}
function getValue<T>(okType: Ok<T>): T;
function getValue<E>(errorType: Err<E>): E;
function getValue<T, E>(result: Result<T, E>): T | E {
return result.value;
}
class FooError extends Error {
constructor() {
super('I am a FooError');
Object.setPrototypeOf(this, FooError.prototype);
}
}
class BarError extends Error {
constructor() {
super('I am a BarError');
Object.setPrototypeOf(this, BarError.prototype);
}
}
export function someFunc(input: number): Result<number, FooError | BarError> {
if (input % 3 === 0) {
return ok(input * 3);
} else if (input === 1) {
return error(new FooError());
} else {
return error(new BarError());
}
}
const result = someFunc(1);
if (isOk(result)) {
// has type "number"
const value = getValue(result);
} else {
// has type "FooError | BarError"
const value = getValue(result);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment