Home > Enterprise >  How do you check for undefined when using an expression as the property name of object in Typescript
How do you check for undefined when using an expression as the property name of object in Typescript

Time:12-24

Consider the following code:

type Props = 'foo' | 'bar';
type ParRec = Partial<Record<Props, string>>;

function doSomething (item: ParRec) {
  const props: Props[] = ['foo', 'bar'];
  return props.map((prop) => {
    if(item[prop]) {
      const result: string = item[prop];
      return { result };
    }
    return {};
  });
} 

typescript complains with ts(2322) where const result is declared that string | undefined is not assignable to type string.

The conditional truthy check if(item[prop]) should ensure that it is not undefined.

This seems to only be a problem when using an expression as the property name of item, as the following code has no problem:

function doSomething (item: ParRec) {
  const props: Props[] = ['foo', 'bar'];
  return props.map((prop) => {
    if(item.foo) { // using item['foo'] also works fine
      const result: string = item.foo;
      return { result };
    }
    return {};
  });
} 

I could understand if the object definition was more ambiguous, but I am using the same union type to define both the expression I am using as a property name, as well as the object type definition itself. Is there another way to ensure that item[prop] is not undefined I am not aware of for strict mode?

I am using typescript 4.8.4, and this code is made to simply describe the type error, not to represent any actual functionality.

CodePudding user response:

You can assign the result of item[prop] to a variable and use the variable in the check

Playground

function doSomething (item: ParRec) {
  const props: Props[] = ['foo', 'bar'];
  return props.map((prop) => {
    const result = item[prop]; // string | undefined
    if(result) { // narrowed to string
      return { result };
    }
    return {};
  });
} 
  • Related