@fgv/ts-utils
v4.0.2
Published
Assorted Typescript Utilities
Downloads
11,885
Readme
Summary
Assorted typescript utilities that I'm tired of copying from project to project. Most notable and closest to production-ready are:
- Result<T> - Easily combine inline and exception-based error handling
- Converter<T> - Conversion framework especially useful for type-safe processing of JSON
Installation
With npm:
npm install @fgv/ts-utils
API Documentation
Extracted API documentation is here.
Overview
The Result Pattern
A Result<T> represents the success or failure of executing some operation. A successful result contains a return value of type T, while a failure result contains an error message of type string. Taken by itself, the use of Result<T> allows for simple inline error handling.
const result = functionReturningResult();
if (result.isSuccess()) {
functionAcceptingT(result.value);
}
else {
console.log(result.error);
}
Use succeed<T>() and fail<T>() to return success or failure:
function thisFunctionSucceeds(): string {
return succeed('I succeeded!');
}
function thisFunctionFails(): number {
return fail('Oops! I failed');
}
Use orDefault when a failure can be safely ignored:
// returns undefined on failure
const value1: string|undefined = functionReturningResult('whatever').orDefault();
// returns 'oops' on failure
const value2: string = functionReturningResult('whatever').orDefault('oops');
The orThrow method converts a failure result to an exception, for use in contexts (such as constructors) in which an exception is the most appropriate way to handle errors.
constructor(param: string) {
this._param = validateReturnsResult(param).orThrow();
}
The captureResult function converts an exception to a failure for simplified inline processing.
class Thing {
static create(param: string): Result<Thing> {
return captureResult(new Thing(param));
}
}
Other methods and helpers allow for chaining and conversion of results, working with mulitple results and more. See the API documentation for details.
Converters
The basic Converter<T> implements a convert method which converts unknown to T, using the result pattern to report success or failure.
class Converter<T> {
public convert(from: unknown): Result<T>;
}
But built-in converters, including converters which can extract a field for an object or which apply converters according to the shape of some object can be composed to provide compact and legible type-safe conversion from anything to a strongly typed Typescript object:
interface Thing {
title: string;
count: number;
isGood: boolean;
hints: string[];
}
const thingConverter = Converters.object<Thing>({
title: Converters.string,
count: Converters.number,
isGood: Converters.boolean,
hints: Converters.array(Converters.string),
});
// gets a Thing or throws an error
const thing: Things = thingConverter.convert(json).orThrow();
Everything is strongly-typed, so Intellisense will autocomplete properties and highlight errors in the object supplied to Converters.object.
Other helpers and methods enable optional values or fields, chaining of results and a variety of other conversions and transformations.