Home > Mobile >  How to check if a key exists in Partial?
How to check if a key exists in Partial?

Time:04-21

I have an object typed Partial. I want to check if a given key exists in the object. The below code doesn't work. Does anybody know how to? I'm using Typescript 4.6. Thanks in advance.

type Name = 'dog' | 'cat' | 'bird'

function(obj: Partial<Record<Name, number>>, name: Name) {
  // check a given name exists in obj
  if (name in obj) {
    const v = obj[name] // number or undefined
  }
  // Wait, how about dot notation? 
  if ('dog' in obj) {
    const v = obj.dog  // number or undefined
  }
  if (obj.dog !== undefined) {
    const v = obj.dog  // number or undefined
  }
}

CodePudding user response:

TypeScript doesn't refine the type of your obj argument, even within each of those conditions it will still be Partial<Record<Name, number>>.

However, you can narrow the type of a variable that was assigned the value of that property in obj. For example:

type Name = 'dog' | 'cat' | 'bird'

function fn(obj: Partial<Record<Name, number>>, name: Name) {
  // check a given name exists in obj
  const v1 = obj[name];
  if (v1) {
    // v1: number
  }

  const v2 = obj.dog;
  if (v2) {
    // v2: number
  }
}

TypeScript Playground

TypeScript doesn't do that level of type narrowing where it would apply to only a single property of an object. I believe the only time when checking an object's properties can narrow the type of object is when you're working with a disciminated union.

This is why, for example, you can do things like this:

type MyType = {
  key: 'a',
  value: number,
} | {
  key: 'b',
  value: string;
};

function (arg: MyType) {
  if (arg.key === 'a') {
    // arg.value: number
  } else {
    // arg.value: string
  }
}

TypeScript Playground

CodePudding user response:

You could do like this:

type Name = 'dog' | 'cat' | 'bird'

function test(obj: Partial<Record<Name, number>>, name: Name) {

  // First you assign the value to a const
  const v = obj[name];
  
  // then you test the value of that const
  if(v !== undefined){
    // do stuff with `v`, now type is inferred correctly
    console.log(v);
  }
}

Demo: https://tsplay.dev/N9EQqN

  • Related