-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherrors.ts
More file actions
50 lines (42 loc) · 1.56 KB
/
errors.ts
File metadata and controls
50 lines (42 loc) · 1.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
export type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };
export type AppError<ErrorName extends string, Extra = {}> = Error & Extra & { name: ErrorName };
export const ok = <T>(value: T): Result<T, never> => ({ ok: true, value });
export const err = <E>(error: E): Result<never, E> => ({ ok: false, error });
export function defineError<ErrorName extends string, Extra extends object = {}>(
name: ErrorName,
messageTemplate: (extra: Extra) => string
) {
class CustomError extends Error {
constructor(extra: Extra) {
super(messageTemplate(extra));
Object.setPrototypeOf(this, new.target.prototype);
this.name = name;
Object.assign(this, extra);
}
}
return CustomError as unknown as {
new (extra: Extra): AppError<ErrorName, Extra>;
};
}
/**
import { Result, ok, err, defineError } from "./errors";
export const NegativeIndexError = defineError(
"NegativeIndexError",
({ index }: { index: number }) => `Index must be non-negative, got ${index}`
);
export type GetItemsError = InstanceType<typeof NegativeIndexError> | ... other errors;
function getItem(xs: number[], index: number): Result<number, GetItemsError> {
if (index < 0) {
return err(new NegativeIndexError({ index }));
}
return ok(xs[index]);
}
const result = getItem([1, 2, 3], -1);
if (!result.ok) {
if (result.error instanceof NegativeIndexError) {
// fully typed:
console.log(result.error.index); // number
console.log(result.error.message);
}
}
*/