I am posting to see if anyone has a cleaner way of checking for non-false values in JS/TS files.
Over the years, I've had several attempts of writing cleaner if statements to check for non-falsy values as it triggers me how they all do the same thing but are pretty lengthy and end up taking half of some code files.
I tried creating functions and typing them in different ways to encapsulate logging and then throwing errors, but TS doesn't accept this as a safe check. So far, the only thing satisfying the check is a standard if statement, with the error thrown directly in the body.
Is there no better, less verbose way of handling these repetitive checks while maintaining safety?
Stadandard checks
// Not falsy check
if (!plan) {
Log.log.stripe_webhook("Plan not found");
throw new Error("Plan not found");
}
// Another not falsy check
if (!currentUser.email) {
Log.log.stripe_webhook("Current user does not have an email");
throw new Error("Current user does not have an email");
}
Things I've tried
Helper functions. I tried several ones over time, but here is a basic example, which TS doesn't accept.
// Function to ensure no false values. TS does not accept this as safe.
function ensureNotFalsy(
condition: any,
errorMessage: string
): void {
if (!condition) {
Log.log.stripe_webhook(errorMessage);
throw new Error(errorMessage);
}
}
// Not falsy checks
ensureNotFalsy(orgRef, "Organization reference not found");
ensureNotFalsy(orgRef?.organization, "Organization not found");
ensureNotFalsy(
orgRef!.organization!.id,
"Organization ID not found"
);
// ...Code below will still throw errors saying these checked values could be undefined.
Adding the errors and handling in a const. Doesn't work either. TS, seems to require the error to be thrown in each if statement.
// Put logic in a const. TS doesn't recognize it as a safe.
const throwError = (message: string) => {
Log.log.stripe_webhook(message);
throw new Error(message);
};
// Checks to ensure not falsy. Doesn't work with TS.
if (!plan) throwError("Plan not found");
if (!currentUser.email)
throwError("Current user does not have an email");
// ...Code below will still throw errors saying these checked values could be undefined.
Assertion functions are designed for exactly this purpose. Simply use asserts condition
instead of void
for the return type of ensureNotFalsy
, and it should work.
Here is an example:
function ensureNotFalsy(
condition: any,
errorMessage: string
): asserts condition {
if (!condition) {
throw new Error(errorMessage);
}
}
const f = (orgRef: {organization?: {id?: string}} | null) => {
ensureNotFalsy(orgRef, "Organization reference not found");
ensureNotFalsy(orgRef.organization, "Organization not found");
ensureNotFalsy(
orgRef.organization.id,
"Organization ID not found"
);
}