All files / src/utils/common empty.ts

100% Statements 30/30
100% Branches 2/2
100% Functions 12/12
100% Lines 25/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113      47x                         1300x         47x                         47x 2488x   47x 47x 1x     47x   47x 1x     47x           47x           47x                         47x   47x 47x 1x     47x   47x 1x     47x           47x           47x                         47x  
/**
 * An immutable empty array.
 */
export const EMPTY_ARRAY: readonly unknown[] = Object.freeze([]);
 
/**
 * A function that returns {@link EMPTY_ARRAY the immutable empty array}, useful when type inference is needed.
 *
 * @example:
 * ```ts
 * import { emptyArray } from 'emitnlog/utils';
 *
 * const accounts: readonly Account[] = getAccounts() ?? emptyArray();
 * console.log(accounts.length);
 * ```
 */
export const emptyArray = <T>(): readonly T[] => EMPTY_ARRAY as readonly T[];
 
/**
 * An immutable empty record.
 */
export const EMPTY_RECORD: { readonly [key: string | number | symbol]: unknown } = Object.freeze({});
 
/**
 * A function that returns {@link EMPTY_RECORD the immutable empty record}, useful when type inference is needed.
 *
 * @example:
 * ```ts
 * import { emptyRecord } from 'emitnlog/utils';
 *
 * const record: Readonly<Record<string, number>> = emptyRecord();
 * console.log(record.a);
 * ```
 */
export const emptyRecord = <K extends string | number | symbol, V>(): { readonly [key in K]: V } =>
  EMPTY_RECORD as { readonly [key in K]: V };
 
const createImmutableSet = <T>(target = new Set<T>()): ReadonlySet<T> => {
  const add: Set<T>['add'] = () => {
    throw new TypeError('Cannot modify an immutable set.');
  };
 
  const deleteFn: Set<T>['delete'] = () => false;
 
  const clear: Set<T>['clear'] = () => {
    throw new TypeError('Cannot modify an immutable set.');
  };
 
  Object.defineProperties(target, {
    add: { value: add, writable: false, enumerable: false, configurable: false },
    delete: { value: deleteFn, writable: false, enumerable: false, configurable: false },
    clear: { value: clear, writable: false, enumerable: false, configurable: false },
  });
 
  return Object.freeze(target);
};
 
/**
 * An immutable empty set.
 */
export const EMPTY_SET: ReadonlySet<unknown> = createImmutableSet();
 
/**
 * A function that returns {@link EMPTY_SET the immutable empty set}, useful when type inference is needed.
 *
 * @example:
 * ```ts
 * import { emptySet } from 'emitnlog/utils';
 *
 * const names: ReadonlySet<string> = getNameSet() ?? emptySet();
 * console.log(names.size);
 * ```
 */
export const emptySet = <T>(): ReadonlySet<T> => EMPTY_SET as ReadonlySet<T>;
 
const createImmutableMap = <K, V>(target = new Map<K, V>()): ReadonlyMap<K, V> => {
  const setValue: Map<K, V>['set'] = () => {
    throw new TypeError('Cannot modify an immutable map.');
  };
 
  const deleteFn: Map<K, V>['delete'] = () => false;
 
  const clear: Map<K, V>['clear'] = () => {
    throw new TypeError('Cannot modify an immutable map.');
  };
 
  Object.defineProperties(target, {
    set: { value: setValue, writable: false, enumerable: false, configurable: false },
    delete: { value: deleteFn, writable: false, enumerable: false, configurable: false },
    clear: { value: clear, writable: false, enumerable: false, configurable: false },
  });
 
  return Object.freeze(target);
};
 
/**
 * An immutable empty map.
 */
export const EMPTY_MAP: ReadonlyMap<unknown, unknown> = createImmutableMap();
 
/**
 * A function that returns {@link EMPTY_MAP the immutable empty map}, useful when type inference is needed.
 *
 * @example:
 * ```ts
 * import { emptyMap } from 'emitnlog/utils';
 *
 * const map: ReadonlyMap<string, number> = emptyMap();
 * console.log(map.size);
 * ```
 */
export const emptyMap = <K, V>(): ReadonlyMap<K, V> => EMPTY_MAP as ReadonlyMap<K, V>;