How to create type by picking keys from an object that have values

Viewed 40

So I've got this big object

const bigObject = {
  propA: "sup",
  propB: "hi",
  propC: undefined,
  propD: "",
  propE: "hello",
  propF: null,
}

And I want to make a type which is the keys of my bigObject, but only if that key has a value:

// what I have so far which doesn't quite work
type LittleObject = {
  [x in keyof typeof bigObject]: number
}

↑↑↑↑ This type is too permissive. It shapes objects so their keys could be anything from propA to propF. I want a type that would only allow propA, probB, and propE because they have truthy values.

1 Answers

You can use key remapping to test each key for the types you want and then conditionally set the key to never to remove it from the resulting object type.

const bigObject = {
  propA: "sup",
  propB: "hi",
  propC: undefined,
  propD: "",
  propE: "hello",
  propF: null,
} as const
// added as const so you can tell the difference so that
// "" does not get widened to string

type LittleObject = {
  [
    K in keyof typeof bigObject as
      (typeof bigObject)[K] extends null | undefined | ""
        ? never
        : K
  ]: number 
}

Playground


Admittedly, this is a little odd though. A property type is unlikely to be just undefined in practice. Usually it's undefined | something which means you probably do want that prop to test it. But it's hard to give specific advice from what you've provided so far in your question.

Related