Search code examples
typescriptlodash

Can I have lodash omit return a specific type instead of a partial type?


In the code below

import omit from "lodash/fp/omit";

type EnhancerProps = {
  serializedSvg: string;
  svgSourceId: string;
  containerId: string;
};

const rest = omit(["serializedSvg", "containerId"])(props);

rest is typed as Partial. What can I do to have omit return something more specific, like {svgSourceId: string} instead.


Solution

  • Weird that omit doesn't infer types on its own. I'm not sure if there's a reason for that, but I was able to come up with a helper function that should do the trick.

    function omitWithTypes<A extends ReadonlyArray<keyof B>, B extends Object>(
      typeArray: A,
      obj: B
    ) {
      return omit(typeArray)(obj) as Omit<B, A[number]>;
    }
    

    The Omit utility type will allow you to narrow properties of a type. However if you want to convert the values of an array to a union type and pass to Omit, the array must be read only, which you can satisfy with the as const assertion to tell the TS compiler that it won't mutate.

    const filter = ["serializedSvg", "svgSourceId"] as const;
    const exclusive = omitWithTypes(filter, props);
    

    OR

    const exclusive = omitWithTypes(["serializedSvg", "svgSourceId"] as const, props);
    

    You will get correct inferred types (though it is a little verbose since it's using the Pick utility type behind the scenes):

    enter image description here

    You will even get an error if you try to exclude values that aren't properties of the object being picked from:

    enter image description here