
Product
Socket Now Protects the Chrome Extension Ecosystem
Socket is launching experimental protection for Chrome extensions, scanning for malware and risky permissions to prevent silent supply chain attacks.
@epic-web/invariant
Advanced tools
Type safe utilities for throwing errors (and responses) if things aren't quite right. Inspired by npm.im/invariant
Type safe utilities for throwing errors (and responses) in exceptional situations in a declarative way.
npm install @epic-web/invariant
Your application has boundaries. Network requests/responses, file system reads, etc. When you're working with these boundaries, you need to be able to handle errors that may occur, even in TypeScript.
TypeScript will typically make these boundaries much more obvious because it doesn't like not knowing what the type of something is. For example:
const formData = new FormData(formElement)
const name = await formData.get('name')
// name is `File | string | null`
Often it's a good idea to use a proper parsing library for situations like this, but for simple cases that can often feel like overkill. But you don't want to just ignore TypeScript because:
TypeScript is that brutally honest friend you put up with because they save you from making terrible mistakes. – @kentcdodds
So you check it:
const formData = new FormData(formElement)
const name = await formData.get('name')
// name is `File | string | null`
if (typeof name !== 'string') {
throw new Error('Name must be a string')
}
// now name is `string` (and TypeScript knows it too)
You're fine throwing a descriptive error here because it's just very unlikely this will ever happen and even if it does you wouldn't really know what to do about it anyway.
It's not a big deal, but there's a tiny bit of boilerplate that would be nice to
avoid. Especially when you find yourself doing this all over the codebase. This
is the problem @epic-web/invariant
solves.
Here's the diff from what we had above:
const formData = new FormData(formElement)
const name = await formData.get('name')
// name is `File | string | null`
- if (typeof name !== 'string') {
- throw new Error('Name must be a string')
- }
+ invariant(typeof name === 'string', 'Name must be a string')
// now name is `string` (and TypeScript knows it too)
It's pretty simple. But honestly, it's nicer to read, it throws a special
InvariantError
object to distinguish it from other types of errors, and we
have another useful utility for throwing Response
objects instead of Error
objects which is handy
in Remix.
invariant
The invariant
function is used to assert that a condition is true. If the
condition is false, it throws an error with the provided message.
Basic Usage
import { invariant } from '@epic-web/invariant'
const creature = { name: 'Dragon', type: 'Fire' }
invariant(creature.name === 'Dragon', 'Creature must be a Dragon')
Throwing a Response on False Condition
import { invariant } from '@epic-web/invariant'
const creature = { name: 'Unicorn', type: 'Magic' }
invariant(creature.type === 'Fire', 'Creature must be of type Fire')
// Throws: InvariantError: Creature must be of type Fire
Using Callback for Error Message
import { invariantResponse } from '@epic-web/invariant'
const creature = { name: 'Elf', type: 'Forest' }
invariant(creature.type === 'Water', () => 'Creature must be of type Water')
// Throws: InvariantError: Creature must be of type Water
invariantResponse
The invariantResponse
function works similarly to invariant
, but instead of
throwing an InvariantError
, it throws a Response object.
Basic Usage
import { invariantResponse } from '@epic-web/invariant'
const creature = { name: 'Phoenix', type: 'Fire' }
invariantResponse(creature.type === 'Fire', 'Creature must be of type Fire')
Throwing a Response on False Condition
import { invariantResponse } from '@epic-web/invariant'
const creature = { name: 'Griffin', type: 'Air' }
invariantResponse(creature.type === 'Water', 'Creature must be of type Water')
// Throws: Response { status: 400, body: 'Creature must be of type Water' }
The response status default if 400 (Bad Request), but you'll find how to change that below.
Using Callback for Response Message
import { invariantResponse } from '@epic-web/invariant'
const creature = { name: 'Mermaid', type: 'Water' }
invariantResponse(
creature.type === 'Land',
() => `Expected a Land creature, but got a ${creature.type} creature`,
)
Throwing a Response with Additional Options
import { invariantResponse } from '@epic-web/invariant'
const creature = { name: 'Cerberus', type: 'Underworld' }
invariantResponse(
creature.type === 'Sky',
JSON.stringify({ error: 'Creature must be of type Sky' }),
{ status: 500, headers: { 'Content-Type': 'text/json' } },
)
There are three main differences. With @epic-web/invariant
:
invariantResponse
.MIT
FAQs
Type safe utilities for throwing errors (and responses) if things aren't quite right. Inspired by npm.im/invariant
The npm package @epic-web/invariant receives a total of 189,967 weekly downloads. As such, @epic-web/invariant popularity was classified as popular.
We found that @epic-web/invariant demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket is launching experimental protection for Chrome extensions, scanning for malware and risky permissions to prevent silent supply chain attacks.
Product
Add secure dependency scanning to Claude Desktop with Socket MCP, a one-click extension that keeps your coding conversations safe from malicious packages.
Product
Socket now supports Scala and Kotlin, bringing AI-powered threat detection to JVM projects with easy manifest generation and fast, accurate scans.