use typed-redux-saga in flash-firmware sagas

This make things a bit more type safe and a bit easier to read.
This commit is contained in:
David Lechner
2021-01-21 22:22:46 -06:00
parent ab0c850b80
commit 218dda4d0b
5 changed files with 267 additions and 147 deletions
+11 -4
View File
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020 The Pybricks Authors
import { assert, hex, maybe } from '.';
import { assert, defined, hex, maybe } from '.';
test('assert', () => {
const assertTrue = jest.fn(() => assert(true, 'should not throw'));
@@ -11,14 +11,21 @@ test('assert', () => {
expect(() => assert(false, 'should throw')).toThrow();
});
describe('defined', () => {
expect(() => defined('test')).not.toThrow();
expect(() => defined(undefined)).toThrowError();
});
describe('maybe', () => {
test('resolved', async () => {
const result = await maybe(Promise.resolve('test'));
const [result, error] = await maybe(Promise.resolve('test'));
expect(result).toBe('test');
expect(error).toBeUndefined();
});
test('rejected', async () => {
const result = await maybe(Promise.reject(new Error('test')));
expect(result).toBeInstanceOf(Error);
const [result, error] = await maybe(Promise.reject(new Error('test')));
expect(result).toBeUndefined();
expect(error).toBeInstanceOf(Error);
});
});
+13 -4
View File
@@ -7,20 +7,29 @@
* @param condition A condition that is assumed to be true
* @param message Informational message for debugging
*/
export function assert(condition: boolean, message: string): void {
export function assert(condition: boolean, message: string): asserts condition {
if (!condition) {
throw Error(message);
}
}
export type Maybe<T> = T | Error;
/**
* Asserts that an object is not undefined. This is used to make the type
* checker happy with `maybe()` and saga `race()` and `all()` effects where
* we have the condition "if A is undefined, then B is not undefined".
*/
export function defined<T>(obj: T): asserts obj is NonNullable<T> {
assert(obj !== undefined, 'undefined object');
}
export type Maybe<T> = [T?, Error?];
/** Wraps a promise in try/catch and returns the promise result or error. */
export async function maybe<T>(promise: Promise<T>): Promise<Maybe<T>> {
try {
return await promise;
return [await promise];
} catch (err) {
return err;
return [undefined, err];
}
}