Skip to content

Instantly share code, notes, and snippets.

@LorisSigrist
Last active November 18, 2023 23:47
Show Gist options
  • Save LorisSigrist/d1fdf4b390d161bc1afe3793d0a63352 to your computer and use it in GitHub Desktop.
Save LorisSigrist/d1fdf4b390d161bc1afe3793d0a63352 to your computer and use it in GitHub Desktop.
Result Type in Typescript
type TypeMap = {
[key: string]: any
}
type Entries<T extends TypeMap> = {
[K in keyof T]: [K, T[K]];
}[Extract<keyof T, string>];
export type OkResult<OkVal> = {
ok: true,
value: OkVal
}
type BadResultFromEntry<E extends Entries<any>> = E extends [infer K, infer V]
? BadResult<Extract<K, string>, V>
: never;
export type BadResult<ErrorKey extends string, ErrorValue> = {
ok: false,
error: ErrorKey,
value: ErrorValue
}
export type Result<OkVal, ErrorMap extends TypeMap> =
OkResult<OkVal> |
BadResultFromEntry<Entries<ErrorMap>>;
export const Result = {
ok<V>(value: V): OkResult<V> {
return {
ok: true,
value: value
}
},
bad<E extends string, V>(error: E, value: V): BadResult<E, V> {
return {
ok: false,
error: error,
value: value
}
}
}
import { Result } from "./results.js";
import type { Todo } from "./todo.ts";
//Give it the success value, and a map of all possible errors
type FetchTodosResult = Result<Todo[], {
network_failed: unknown,
unauthorized: Response,
}>
//Creating
const result : FetchTodosResult = Result.ok(todos);
const result : FetchTodosResult = Result.bad("network_failed", e);
const result : FetchTodosResult = Result.bad("unauthorized", unauthorizedResponse);
//Consuming
if(!result.ok) {
switch(result.error) {
case "network_failed": {
console.error("Nework failed: ", result.value);
break;
}
case "unauthorized": {
console.error("Unauthorized: ", result.value);
break;
}
}
return;
}
const okValue = result.value;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment