Search
⌘K

Object

Utilities for working with objects, like pick and omit.

Example Usage

omit

Omit properties from an object, with intellisence support for property names.
Returns a new object, without the omitted properties.

import { omit } from './object';

const item = {
  id: 56,
  name: 'Luke',
}
omit(item, ['id'])
// ⏬
{ 
  name: 'Luke' 
}

pick

Pick properties from an object, with intellisence support for property names.
Returns a new object, with only the picked properties.

import { pick } from './object';

const item = {
  id: 56,
  name: 'Luke',
}
pick(item, ['id'])
{ 
  id: 56 
}

groupBy

Group items of an array by a single key.
The key is dynamically extracted by you with the getGroupKey function.

import { groupBy } from './object';

const items = [
  { group: 'one', name: 'Luke' },
  { group: 'one', name: 'Leia' },
  { group: 'two', name: 'Han' },
];
groupBy(items, (item) => item.group);
// ⏬
{
  one: [
    { group: 'one', name: 'Luke' },
    { group: 'one', name: 'Leia' },
  ],
  two: [
    { group: 'two', name: 'Han' },
  ],
}

Dependencies

No dependencies

Auto Install

npx shadcn@latest add https://shadcn-registry-ts.vercel.app/r/util-object.json

Manual Install

object.ts
/**
 * Omit keys from an object
 * 
 * @example
 * ```ts
 * const item = {
 *   id: 56,
 *   name: 'Luke',
 * }
 * const output = omit(item, ['id'])
 * // { name: 'Luke' }
 * ```
 */
export const omit = <
  TObj extends Record<string, any>,
  TKeysToOmit extends Array<keyof TObj>,
  TOutput extends Omit<TObj, TKeysToOmit[number]>
>(
  obj: TObj,
  keysToOmit: TKeysToOmit,
) => {
  const output = { ...obj };
  keysToOmit.forEach(key => {
    delete output[key];
  });
  return output as unknown as TOutput;
};


/**
 * Pick keys of an object
 * 
 * @example
 * ```ts
 * const item = {
 *   id: 56,
 *   name: 'Luke',
 * }
 * const output = pick(item, ['id'])
 * // { id: 56 }
 * ```
 */
export const pick = <
  TObj extends Record<string, any>,
  TKeysToPick extends Array<keyof TObj>,
  TOutput extends Pick<TObj, TKeysToPick[number]>
>(
  obj: TObj,
  keysToPick: TKeysToPick,
) => {
  const output = {};
  keysToPick.forEach(key => {
    // @ts-expect-error key is not in obj
    output[key] = obj[key];
  });
  return output as TOutput;
};


/**
 * Group an array by a key
 * 
 * @example
 * ```ts
 * const items = [
 *   { group: 'one', name: 'Luke' },
 *   { group: 'one', name: 'Leia' },
 *   { group: 'two', name: 'Han' },
 * ]
 * const grouped = groupBy(items, (item) => item.group);
 * // ⏬
 * {
 *   one: [
 *     { group: 'one', name: 'Luke' },
 *     { group: 'one', name: 'Leia' },
 *   ],
 *   two: [
 *     { group: 'two', name: 'Han' },
 *   ],
 * }
 * ```
 */
export const groupBy = <TItem>(
  /** The array of items to group by */
  array: TItem[],
  /** Fn executed for each item that must return a string that is used as key of group */
  getGroupKey: (item: TItem) => string
): { [key: string]: TItem[]; } => {
  return array.reduce((acc, item) => {
    const key = getGroupKey(item);
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(item);
    return acc;
  }, {} as { [key: string]: TItem[]; });
};

Test

object.test.ts
import { describe, it, expect } from 'vitest';

import { pick, omit, groupBy } from './object';

describe('object - pick', () => {

  it('do it', () => {
    expect(pick({ id: 56, name: 'Luke' }, ['id'])).toMatchObject({ id: 56 });
    // @ts-expect-error NON_EXISTING is not in obj
    expect(pick({ id: 56, name: 'Luke' }, ['NON_EXISTING'])).toMatchObject({ NON_EXISTING: undefined });
  });

});

describe('object - omit', () => {

  it('do it', () => {
    expect(omit({ id: 56, name: 'Luke' }, ['id'])).toMatchObject({ name: 'Luke' });
    // @ts-expect-error NON_EXISTING is not in obj
    expect(omit({ id: 56, name: 'Luke' }, ['NON_EXISTING'])).toMatchObject({ id: 56, name: 'Luke' });
  });

});

describe('object - groupBy', () => {

  it('do it', () => {
    const items = [
      { group: 'one', name: 'Luke' },
      { group: 'one', name: 'Leia' },
      { group: 'two', name: 'Han' },
    ];
    const grouped = groupBy(items, (item) => item.group);
    expect(grouped).toMatchObject({
      one: [
        { group: 'one', name: 'Luke' },
        { group: 'one', name: 'Leia' },
      ],
      two: [
        { group: 'two', name: 'Han' },
      ],
    });
  });

});

Command Palette

Search for a command to run...