Errors in TypeScript
In TypeScript, error handling is typically done using exceptions, which is different from Go’s approach. However, we can create a similar pattern using custom error types and a Result type. Here’s how we might implement the example:
// Define a custom Error type
class CustomError extends Error {
constructor(message: string) {
super(message);
this.name = "CustomError";
}
}
// Define sentinel errors
const ErrOutOfTea = new CustomError("no more tea available");
const ErrPower = new CustomError("can't boil water");
// Define a Result type to mimic Go's multiple return values
type Result<T, E = Error> = { ok: T; err: null } | { ok: null; err: E };
function f(arg: number): Result<number> {
if (arg === 42) {
return { ok: null, err: new CustomError("can't work with 42") };
}
return { ok: arg + 3, err: null };
}
function makeTea(arg: number): Result<null> {
if (arg === 2) {
return { ok: null, err: ErrOutOfTea };
} else if (arg === 4) {
// Wrapping errors
return { ok: null, err: new CustomError(`making tea: ${ErrPower.message}`) };
}
return { ok: null, err: null };
}
function main() {
for (const i of [7, 42]) {
const result = f(i);
if (result.err) {
console.log("f failed:", result.err.message);
} else {
console.log("f worked:", result.ok);
}
}
for (let i = 0; i < 5; i++) {
const result = makeTea(i);
if (result.err) {
if (result.err === ErrOutOfTea) {
console.log("We should buy new tea!");
} else if (result.err.message.includes(ErrPower.message)) {
console.log("Now it is dark.");
} else {
console.log("unknown error:", result.err.message);
}
continue;
}
console.log("Tea is ready!");
}
}
main();
In this TypeScript version:
We define a
CustomError
class that extends the built-inError
class.We create sentinel errors using
CustomError
instances.We define a
Result
type that mimics Go’s multiple return values, containing either a successful value (ok
) or an error (err
).The
f
andmakeTea
functions returnResult
objects instead of using multiple return values.In the
main
function, we use theResult
type to check for errors and handle them accordingly.To check for specific errors, we compare directly with sentinel errors or check the error message.
Error wrapping is simulated by including the message of one error in another.
This approach provides a similar error-handling pattern to the Go example, allowing for explicit error checking and the use of sentinel errors. However, it’s worth noting that this is not idiomatic TypeScript/JavaScript, where try-catch blocks are more commonly used for error handling.
To run this TypeScript code, you would typically compile it to JavaScript and then run it with Node.js:
$ tsc errors.ts
$ node errors.js
f worked: 10
f failed: can't work with 42
Tea is ready!
Tea is ready!
We should buy new tea!
Tea is ready!
Now it is dark.
This example demonstrates how to implement a Go-like error handling pattern in TypeScript, but remember that in real-world TypeScript applications, you would more likely use exceptions and try-catch blocks for error handling.