Search
⌘K

Object

Utilities for working with objects, like pick and omit.

Example Usage

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

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

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

// groupBy
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
/**
 * Source: http://localhost:3000
 */

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


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


/**
 * 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 = <T>(
  array: T[],
  getGroupKey: (item: T) => string
): { [key: string]: T[]; } => {
  return array.reduce((acc, item) => {
    const key = getGroupKey(item);
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(item);
    return acc;
  }, {} as { [key: string]: T[]; });
};

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...