'How to handle the type of the value returned by lodash.omitBy?

omitFalsyFields generic function will remove the key which value is falsy('', undefined, null, etc...) of an object.

import _, { Dictionary } from 'lodash';

export function omitFalsyFields<T extends Dictionary<any>>(params: T) {
  return _.omitBy(params, (k) => !k);
}

interface CreateUserParams {
  name?: string;
  email: string;
}

const params: CreateUserParams = omitFalsyFields({ name: '', email: '[email protected]' })

I expect the type of its returned value is CreateUserParams type. The value of params is { email: '[email protected]' }, so the type is compatible with CreateUserParams.

But, got TS type error:

Property 'email' is missing in type 'Dictionary' but required in type 'CreateUserParams'

TypeScript Playground



Solution 1:[1]

If you want to make this function generic, you can do the following:

export function omitFalsyFields<T>(params: T): Dictionary<T> {
  return _.omitBy(params, (k: any) => !k);
}

Now you can pass any type and it should be applied to the input and output

const params = omitFalsyFields<CreateUserParams>({
  name: "",
  email: "[email protected]"
})

But one caveat about this is that omitBy returns a Dictionary<any>, even doing Dictionary<T> it will always casts to any because it's very hard to infer types at runtime if not impossible sometimes, therefore if you want to assign a custom return type or assign the generic T type as output, do the following:

// note that T is an alias for you generic type
export function omitFalsyFields<T>(params: T) {
  // use the "as" keyword to override the returned type from omitBy.
  // With partial you change all properties of T to optional,
 // as omitBy removes falsy properties it makes sense to apply this utility
  return _.omitBy(params, (k: any) => !k) as Partial<T>;
}

const params = omitFalsyFields...
console.log(params.name) // undefined
console.log(params.email) // [email protected]

Doing so, the specific type will be passed to the output as well, take a look at the complete example.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yago Biermann