UNPKG

set-array

Version:
87 lines (82 loc) 2.89 kB
export type Index = `${number}${'+' | ''}` | number | '*' export type Updates<T> = { [U in Index]?: T | T[] } export interface Options<T> { /** * By default, the `updates` items override the original `array`'s items. * The `merge` option can be used to merge those instead. * * If an array of items is being added, `merge()` is called once per item. * * `merge()` is not called when the update's key ends with `+`, i.e. when * items are being prepended. * * `merge()` is called even if the update's index is out-of-bound, with * `oldValue` being `undefined`. * * @example * ```js * const merge = (oldValue, newValue) => [oldValue, newValue] * * set(['a', 'b', 'c'], { 1: 'X' }, { merge }) // ['a', ['b', 'X'], 'c'] * set(['a', 'b', 'c'], { '*': 'X' }, { merge }) // [['a', 'X'], ['b', 'X'], ['c', 'X']] * set(['a', 'b', 'c'], { 1: ['X', 'Y'] }, { merge }) // ['a', ['b', 'X'], ['b', 'Y'], 'c'] * set(['a', 'b', 'c'], { '1+': 'X' }, { merge }) // ['a', 'X', 'b', 'c'] * set(['a', 'b', 'c'], { 4: 'X' }, { merge }) // ['a', 'b', 'c', undefined, [undefined, 'X']] * ``` */ merge?: (oldValue: T, newValue: T) => T } /** * Return a copy of `array` with each of the `updates` applied. * * `updates` values are the items to add. * - Array of values add multiple items * - Empty arrays remove items * * `updates` keys are the `array` indices (before any updates). * - Negative indices match from the end * - `-0` appends items * - If the key ends with `+`, items are prepended, not replaced * - `*` targets all items * * @example * ```js * set(['a', 'b', 'c'], { 1: 'X' }) // ['a', 'X', 'c'] * set(['a', 'b', 'c'], { 1: 'X', 2: 'Y' }) // ['a', 'X', 'Y'] * set(['a', 'b', 'c'], { '*': 'X' }) // ['X', 'X', 'X'] * set(['a', 'b', 'c'], { '-1': 'X' }) // ['a', 'b', 'X'] * set(['a', 'b', 'c'], { 4: 'X' }) // ['a', 'b', 'c', undefined, 'X'] * set(['a', 'b', 'c'], { '-10': 'X' }) // ['X', 'b', 'c'] * set(['a', 'b', 'c'], { '-0': 'X' }) // ['a', 'b', 'c', 'X'] * set(['a', 'b', 'c'], { '1+': 'X' }) // ['a', 'X', 'b', 'c'] * set(['a', 'b', 'c'], { 1: ['X', 'Y'] }) // ['a', 'X', 'Y', 'c'] * set(['a', 'b', 'c'], { 1: [] }) // ['a', 'c'] * set(['a', 'b', 'c'], { 1: ['X'] }) // ['a', 'X', 'c'] * set(['a', 'b', 'c'], { 1: [['X']] }) // ['a', ['X'], 'c'] * set([], { 0: 'X', 2: 'Z' }) // ['X', undefined, 'Z'] * ``` */ export function set<T>( array: T[], updates: Updates<T>, options?: Options<T>, ): T[] /** * Return whether the argument is an object that follows the shape expected by * `set()`. * * @example * ```js * test({ 1: 'X' }) // true * test({ '1+': 'X' }) // true * test({ '-1': 'X' }) // true * test({ '*': 'X' }) // true * test({}) // true * * test({ notAnIndex: 'X' }) // false * test('X') // false * ``` */ export function test(updates: unknown): boolean