4

I want to check if an array inside an object exists, is not null and is not empty

I need to reference that property in bracket notation.

My object

profile = {
    myArray: [1,2,3]
}

And I am checking it like this

const section = "myArray";
if(section in profile && profile[section] && profile[section].length ) { // do something}

I expect this to work but I get an error in this part profile[section].length that says object is possibly null or undefined

If I do it using dot notation it works right

if('myArray' in profile && profile.myArray && profile.myArray.length ) { // do something}
ludwiguer
  • 2,177
  • 2
  • 15
  • 21
  • Typo? `myArray = [1,2,3]` the = should be a colon. – evayly Jul 04 '19 at 18:57
  • @evayly yes, it was a typo, thanks – ludwiguer Jul 04 '19 at 19:04
  • In TypeScript, whenever you use `object[...]` notation, it relies on `object`'s index signature. Because of that, it can't tell that the property you've checked for truthiness is the same property you're accessing the `length` property of. – Patrick Roberts Jul 04 '19 at 19:14

2 Answers2

9

use optional chaining like so

if (profile?.[section]?.length) { // do something }

see https://stackoverflow.com/a/58780897

Andrew
  • 1,406
  • 1
  • 15
  • 23
1

This is a known bug whose fix exists but might not make it into the language due to possible performance issues.

What can we do while we wait? Well, one possible workaround is to introduce a user-defined type guard function which performs the same check internally but forces the compiler to narrow the type of your object the way you were hoping:

function hasDefinedProp<T, K extends keyof T>(
  obj: T,
  k: K
): obj is T & Required<Pick<T, K>> {
  return !!obj[k];
}

The type T & Required<Pick<T, K>> means that it's the same type as T, except that the K-keyed property is required and therefore not nullable/undefined. Let's see it in action:

if (
  section in profile &&
  hasDefinedProp(profile, section) &&
  profile[section].length // okay now
) {
  // do something
}

Looks good! Hope that helps; good luck.

Link to code

jcalz
  • 264,269
  • 27
  • 359
  • 360