A typescript implementation of Rust's Result and Option objects.
Brings compile-time error checking and optional values to typescript.
This package is a friendly fork of the excellent https://github.com/vultix/ts-results/ created due to time constraints on our (Lune's) side – we needed a package available with some fixes.
Notable changes compared to the original package:
Option
gained extra methods: mapOr()
, mapOrElse()
, or()
,
orElse()
Result
also gained extra methods: mapOr()
, mapOrElse()
,
expectErr()
, or()
, orElse()
Ok
and Err
no longer have the val
property – it's Ok.value
and Err.error
nowSome.value
which replaced Some.val
Option.some
-> Option.isSome()
Option.none
-> Option.isNone()
Result.ok
-> Result.isOk()
Result.err
-> Result.isErr()
We'll try to get the changes merged into the upstream package so that this fork can become obsolete.
$ npm install ts-results-es
or
$ yarn add ts-results-es
Convert this:
import { existsSync, readFileSync } from 'fs';
function readFile(path: string): string {
if (existsSync(path)) {
return readFileSync(path);
} else {
// Callers of readFile have no way of knowing the function can fail
throw new Error('invalid path');
}
}
// This line may fail unexpectedly without warnings from typescript
const text = readFile('test.txt');
To this:
import { existsSync, readFileSync } from 'fs';
import { Ok, Err, Result } from 'ts-results-es';
function readFile(path: string): Result<string, 'invalid path'> {
if (existsSync(path)) {
return new Ok(readFileSync(path)); // new is optional here
} else {
return new Err('invalid path'); // new is optional here
}
}
// Typescript now forces you to check whether you have a valid result at compile time.
const result = readFile('test.txt');
if (result.isOk()) {
// text contains the file's content
const text = result.value;
} else {
// err equals 'invalid path'
const err = result.error;
}
Convert this:
declare function getLoggedInUsername(): string | undefined;
declare function getImageURLForUsername(username: string): string | undefined;
function getLoggedInImageURL(): string | undefined {
const username = getLoggedInUsername();
if (!username) {
return undefined;
}
return getImageURLForUsername(username);
}
const stringUrl = getLoggedInImageURL();
const optionalUrl = stringUrl ? new URL(stringUrl) : undefined;
console.log(optionalUrl);
To this:
import { Option, Some, None } from 'ts-results-es';
declare function getLoggedInUsername(): Option<string>;
declare function getImageForUsername(username: string): Option<string>;
function getLoggedInImage(): Option<string> {
return getLoggedInUsername().andThen(getImageForUsername);
}
const optionalUrl = getLoggedInImage().map((url) => new URL(stringUrl));
console.log(optionalUrl); // Some(URL('...'))
// To extract the value, do this:
if (optionalUrl.some) {
const url: URL = optionalUrl.value;
}
See https://ts-results-es.readthedocs.io/en/latest/reference/api/index.html to see the API reference.
The package is published manually right now.
Steps to publish:
package.json
and src/package.json
as neededgit tag -a vX.X.X
(the tag description can be
anything)npm run build && npm publish
master
branch and the new tag to GitHub