5

Due to the nature of Javascript, I get myself checking if a value is != null && != '' all the time, so I created a function to check if values are empty, like this:

const isEmpty = (variable: any, allowEmptyString?: boolean): boolean => {
    return variable == null || (variable == '' && !allowEmptyString);
};

The problem is, other methods don't have a knowledge of what this means, so I have to use ! all the time to prevent warnings, for example:

const foo = (val?: number): void => {
    let a = 0;

    if (!isEmpty(val)) {
        a = val;
        // let a: number;
        // Type 'number | undefined' is not assignable to type 'number'.
        // Type 'undefined' is not assignable to type 'number'
    }
};

My current solution is to do:

if (!isEmpty(val)) {
    a = val!
}

Is there a way to avoid using ! to prevent warnings?

5
  • Since you're only checking for null or empty string it would be the same to just do "if (!val)" instead of "if (!isEmoty(val))" and then you won't be needing the extra ! Commented Aug 20, 2019 at 10:40
  • if (!val) would fail with 0 and false Commented Aug 20, 2019 at 10:41
  • Yeah, sorry you're right. My bad. I tried your code out in VS Code with Typescript 3.5.2 and I don't get the same error as you. It is fine with val as a number and I do not need that extra exclamation mark. What IDE and version of Typescript are you using? Commented Aug 20, 2019 at 10:51
  • @Kamelkent you have to set strictNullChecks to true in your tsconfig.json file. Commented Aug 20, 2019 at 10:53
  • It seems like I'm just taking up your time here.. :) Hope you find the answers you're looking for. Commented Aug 20, 2019 at 10:57

1 Answer 1

6

Here is a solution:

function isEmpty(variable: string | null | undefined, allowEmptyString?: boolean): variable is Exclude<undefined | null, string>
function isEmpty<T>(variable: T | null | undefined): variable is Exclude<undefined | null, T>
function isEmpty(variable: any, allowEmptyString = false): boolean {
    return variable === null 
        || variable === undefined 
        || (variable === '' && !allowEmptyString);
}

Notes:

  • Use === instead of ==;
  • Take care of undefined values;
  • By default (without a parameter allowEmptyString set to true) an empty string is processed as undefined and null, and the compiler will mistakenly believe it is not a string.
  • Parameters of Exclude are reversed in order to simulate a "not" on the boolean value (it works but I'm unsure why).

… or an exists function

But I suggest an exists function in order to avoid the double inversion. It is easier to write, and easier to use:

function exists(variable: string | null | undefined, allowEmptyString?: boolean): variable is string
function exists<T>(variable: T): variable is NonNullable<T>
function exists(variable: any, allowEmptyString = false): boolean {
    return variable !== null 
        && variable !== undefined 
        && (variable !== '' || allowEmptyString);
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot. I've been looking for this for a while now, I thought I'd just have to live with the workarounds.
@GuilhermeLopes You're welcome. Fyi I edited to add precisions.
There was a bug with strings, I edited, it is fixed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.