@taktikorg/quia-exercitationem v3.8.86
@taktikorg/quia-exercitationem
Type-safe implementation of invariant with positionals.
Motivation
Type-safely
This implementation asserts the given predicate expression so it's treated as non-nullable after the invariant
call:
// Regular invariant:
invariant(user, 'Failed to fetch')
user?.firstName // "user" is possibly undefined
// Outvariant:
invariant(user, 'Failed to fetch')
user.firstName // OK, "invariant" ensured the "user" exists
Positionals support
This implementation uses rest parameters to support dynamic number of positionals:
invariant(predicate, 'Expected %s but got %s', 'one', false)
What is this for?
Invariant is a shorthand function that asserts a given predicate and throws an error if that predicate is false.
Compare these two pieces of code identical in behavior:
if (!token) {
throw new Error(`Expected a token to be set but got ${typeof token}`)
}
import { invariant } from '@taktikorg/quia-exercitationem'
invariant(token, 'Expected a token to be set but got %s', typeof token)
Using invariant
reduces the visual nesting of the code and leads to cleaner error messages thanks to formatted positionals (i.e. the %s
(string) positional above).
Usage
Install
npm install @taktikorg/quia-exercitationem
# or
yarn add @taktikorg/quia-exercitationem
You may want to install this library as a dev dependency (
-D
) based on your usage.
Write an assertion
import { invariant } from '@taktikorg/quia-exercitationem'
invariant(user, 'Failed to load: expected user, but got %o', user)
Positionals
The following positional tokens are supported:
Token | Expected value type |
---|---|
%s | String |
%d /%i | Number |
%j | JSON (non-stringified) |
%o | Arbitrary object or object-like (i.e. a class instance) |
Whenever present in the error message, a positional token will look up the value to insert in its place from the arguments given to invariant
.
invariant(
false,
'Expected the "%s" property but got %j',
// Note that positionals are sensitive to order:
// - "firstName" replaces "%s" because it's first.
// - {"id":1} replaces "%j" because it's second.
'firstName',
{
id: 1,
}
)
Polymorphic errors
It is possible to throw a custom Error
instance using invariant.as
:
import { invariant } from '@taktikorg/quia-exercitationem'
class NetworkError extends Error {
constructor(message) {
super(message)
}
}
invariant.as(NetworkError, res.fulfilled, 'Failed to handle response')
Note that providing a custom error constructor as the argument to invariant.as
requires the custom constructor's signature to be compatible with the Error
class constructor.
If your error constructor has a different signature, you can pass a function as the first argument to invariant.as
that creates a new custom error instance.
import { invariant } from '@taktikorg/quia-exercitationem'
class NetworkError extends Error {
constructor(statusCode, message) {
super(message)
this.statusCode = statusCode
}
}
invariant.as(
(message) => new NetworkError(500, message),
res.fulfilled,
'Failed to handle response'
)
Abstract the error into helper functions for flexibility:
function toNetworkError(statusCode) {
return (message) => new NetworkError(statusCode, message)
}
invariant.as(toNetworkError(404), res?.user?.id, 'User Not Found')
invariant.as(toNetworkError(500), res.fulfilled, 'Internal Server Error')
Contributing
Please open an issue or submit a pull request if you wish to contribute. Thank you.
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago