0

I frequently have a collection that might be either undefined or empty. So I write this:

if ((thingies?.length ?? 0) > 0) ...

I guess that's not so bad in the grand scheme, but it ain't pretty. What I really want is a Bash-like operator that means "this variable exists, is an array, and has at least one element":

if (thingies#) ... // it's safe to access thingies[0]

Pretty sure that's not a thing. But what's the most concise Typescript expression of this?

1
  • 1
    if (array?.length) evaluates to a boolean true if it's an array with at least one item. 0 or undefined would both return false, so only positive numbers remain Commented Oct 29, 2022 at 15:32

3 Answers 3

4

I would simply write it like this:

if (Array.isArray(thingies) && thingies.length > 0) {
  [...]
}

Not the shortest way but way more clear (and more correct) in my opinion.

Edit:

If it feels too long and you need it often, you can also simply define it as a function:

import {isNonEmptyArray} from "./utils";

if (isNonEmptyArray(thingies)) {
  [...]
}
// utils.ts
export const isNonEmptyArray = (array: unknown): array is unknown[] => (
  Array.isArray(array) && array.length > 0
)
Sign up to request clarification or add additional context in comments.

2 Comments

Don't forget the type predicate for isNonEmptyArray.
Ah right, I added it :)
1

Considering that both undefined and 0 are falsy values, you can just write:

if (array?.length)

Either array is undefined and this will return false, or it is defined and it will return false if length === 0.

Edit:
If you first wish to ensure that the object is an array, you can perform a check using Array.isArray beforehand:

if (Array.isArray(object) && object.length)

5 Comments

what if its an object {length:7}.
Well, as long as the Typescript definition of your object's type includes a length: number property, then this condition will work just fine.
what I mean is that this will allow non-arrays to pass the condition.
I see, you are definitely right, my solution does not check that the object reference is an Array.
I believe the check for it being an array will make the ?. unneccessary.
0

Answering my own question, a year later: I usually use thing?.length now, but I also frequently make use of the lodash size(thing) and isEmpty(thing) methods for this. That's particularly helpful when particularly when thing might be something else, like a set or an object, or when I need to check if the length is greater than n, where n > 0:

if ((thing?.length ?? 0) > 1) ...            // :(
if (isArray(thing) && thing.length > 1) ...  // :|
if (size(thing) > 1) ...                     // :)

Comments

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.