A Must-Do Discovery for Typescript: Embracing Tiny-Invariant
In software development, the “early exit pattern” involves strategically placing condition checks at the beginning of a function or block of code to promptly exit the execution if certain conditions are not met, enhancing code readability by reducing unnecessary nesting and bringing the main logic into clearer focus.
Enter “tiny-invariant,” a minimalistic yet potent library that enhances clarity and maintainability using the early exit pattern.
Consider an API handler retrieving user data based on a provided username. The goal is clear: proceed only if the username is a non-empty string. Users being users, unexpected inputs are inevitable. With “tiny-invariant,” early exit patterns streamline validation.
// utils.ts
import invariant from 'tiny-invariant';
// Pseudo-implementation of invariant function
// Ensures a condition is met; otherwise, throws an error with a provided message
function invariant(condition: boolean, message: string): asserts condition {
if (!condition) {
throw new Error(message);
}
}
// Updated API handler using tiny-invariant
async function getUser(params: { username?: string }) {
const { username } = params;
invariant(!!username, "Username must be present");
const user = await findUserByUsername(username);
invariant(user !== undefined, "User not found");
return Response.ok(JSON.stringify(user));
}
The invariant
function of the tiny-invariant package provides runtime checks that integrate seamlessly with TypeScript's static type checking. It condenses traditional three-line conditional checks into a single, more concise line, significantly improving the overall brevity and clarity of the code.
As of my current opinion on software engineering patterns, this one is well-intentioned and applicable to all TS codebases. For a refactor hack, just pipe a file into an AI coding assistant and request error handling blocks be changed to using the invariant
function.