Search code examples
typescripttypeguards

How to typeguard filtering Object.entries?


I wish there was something like entryof to typeguard entries like this:

const carDude = {
  name: "Tom",
  age: 45,
  car: "Porsche 911"
}

interface Dude {
  name: string;
  age: number;
}

Object
  .entries(carDude)
  .filter((entry): entry is entryof Dude => 
    entry[0] === "name" || entry[0] === "age"
  )

How to work around that using a typeguard?


Solution

  • I'd be inclined to define EntryOf like this:

    type EntryOf<T extends object> = { [K in keyof T]: [K, T[K]] }[keyof T];
    

    That will take an object type T and make it into a union of entry tuples. Then your code could be written as

    const ret = Object.entries(carDude).filter((entry): entry is EntryOf<Dude> =>
        entry[0] === "name" || entry[0] === "age"
    );
    /* const ret: (["name", string] | ["age", number])[] */
    

    and you see that the returned array type has elements of type ["name", string] | ["age", number], as I assume you wanted.

    Hope that helps; good luck!

    Playground link to code