`omitBy` / `pickBy` types
Author: joshkelCreated Aug 3, 2026Updated Aug 3, 2026
es-toolkit version
1.50.0
Entry point
es-toolkit
Reproduction
import { omitBy } from 'es-toolkit';
interface Item { id: number; name: string; }
type ItemLookup = Record<number, Item>;
function processItems(items: ItemLookup) {}
const items: ItemLookup = {};
processItems(omitBy(items, i => i.name.startsWith('A')));Current vs. expected behavior
Current: TypeScript compilation error:
Argument of type 'Partial<ItemLookup>' is not assignable to parameter of type 'ItemLookup'.
'number' index signatures are incompatible.
Type 'Item | undefined' is not assignable to type 'Item'.
Type 'undefined' is not assignable to type 'Item'.ts(2345)Expected: No errors
This problem is caused by omitBy and pickBy's type definitions stating that they always return a Partial<T>. But Record<string, T> and Record<number, T> are special: they're already Partial, so to speak, because it's impossible to have a record over every string or every number.
By contrast, the es-toolkit/compat versions of the types treat string and number records specially, so they avoid introducing the unwanted Partial:
declare function omitBy<T>(object: Record<string, T> | null | undefined, predicate?: ValueKeyIteratee<T>): Record<string, T>;
declare function omitBy<T>(object: Record<number, T> | null | undefined, predicate?: ValueKeyIteratee<T>): Record<number, T>;
declare function omitBy<T extends object>(object: T | null | undefined, predicate: ValueKeyIteratee<T[keyof T]>): Partial<T>;Validations
- I searched the existing issues and discussions.
- I read the Contributing Guidelines.
- I wrote this description myself.
Source: toss/es-toolkit