简体   繁体   中英

How to check if optional object property exists?

I'm having trouble getting TypeScript to recognise that an optional property of an object is defined.

type OuterKeys = 'a' | 'b';

type Inner = {
    value: '';
}

type Outer = Partial<Record<OuterKeys, Inner>>;

const thisGivesError = (key: OuterKeys, outer: Outer) => {
    if (outer[key]) {
        console.log(outer[key].value);
    }
}

Even though I explicitly check if outer[key] is defined, I'm getting error when trying to access outer[key].value : Object is possibly 'undefined' .

How can I work around it? The only way I found is assigning outer[key] to a variable and having another if , like below. Is this the only way to go?

const thisWorks = (key: OuterKeys, outer: Outer) => {
    const o = outer[key];
    if (o) {
      console.log(o.value);
    }    
}

The playground with the code can be found here

Edit: I don't want to use ! operator, as it feels like a workaround - why would I tell TypeScript that this value is set using non-null assertion, if I already checked for its existence with if ? Same for .? - I already have the if , so this value for sure exists and is not optional.

That's #10530 , currently TS doesn't narrow down on indexed access.

Because the inner object which holds the value is never specified to not be undefined. You can fix this by simply adding a question mark.

Ex adding a question mark:

const thisGivesError = (key: OuterKeys, outer: Outer) => {
    if (outer[key]) {
        console.log(outer[key]?.value);
    }
}

At this point, after checking for outer[key] being truthy, it's safe to go with non-null assertion:

if (outer[key]) {
    console.log(outer[key]!.value);
}

Though I don't know how to make TypeScript figure it out on its own.

You can make use of object?.key operator. You can learn more about it here .

Your final code will be:

const thisWorks = (key: OuterKeys, outer: Outer) => {
  if (outer[key]) {
    console.log(outer[key]?.value);
  }    
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM