import type { StrictEntries } from '../ObjectConstructor/entriesS.js'; import type { StrictKeys } from '../ObjectConstructor/keysS.js'; import type { Size } from '../ObjectConstructor/size.js'; import type { StrictValues } from '../ObjectConstructor/valuesS.js'; import type { BasePath, BasePathArray, GetByPath, OmitByPath, PathFn, } from '../global/path.js'; import type { PropFn } from '../global/prop.js'; import type { Cast } from '../internal/types/assertion.js'; import type { List, Obj, Path } from '../internal/types/tools/index.js'; import type { ListOf } from '../internal/types/union.js'; declare const omitPropFallback: unique symbol; /** * An object with additional methods. */ export type ExtendedObject = O & { /** * Returns the object itself, but hide all additional methods in TS. * * It does **not** actually hide the methods, it just makes them invisible in TS. If you want to hide them also in JS, use `purify` instead. * @example * ```typescript * const obj = { a: 1 }; * const obj2 = { ...ex(obj).filter(([, v]) => v > 0) }; // obj2 :: { a?: number | undefined, keys: () => ..., values: () => ..., ... } * const obj3 = { ...ex(obj).filter(([, v]) => v > 0).mask() }; // obj3 :: { a?: number | undefined } * ``` * * @see {@link ExtendedObject#purify} */ mask: () => O; /** * Returns a new object with all additional methods removed. * * Compared to `mask`, it actually removes the methods and returns a new one, but it also means this is less performant. * @example * ```typescript * const obj = { a: 1 }; * const obj2 = { ...ex(obj).filter(([, v]) => v > 0) }; // obj2 :: { a?: number | undefined, keys: () => ..., values: () => ..., ... } * const obj3 = { ...ex(obj).filter(([, v]) => v > 0).purify() }; // obj3 :: { a?: number | undefined } * ``` * * @see {@link ExtendedObject#mask} */ purify: () => O; /** * Returns the names of the enumerable string properties and methods of the object (using `Object.keysS`). * * @example * ```typescript * const obj = { a: 1, b: 2, c: 3, 5: 42, [Symbol()]: 'symbol' }; * ex(obj).keys(); // => ['5', 'a', 'b', 'c'] * const keys = ex(obj).keys(); // keys :: ('5' | 'a' | 'b' | 'c')[] * ``` * * @example * ```typescript * const obj = { a: 1, b: 2, c: 3, 5: 42, [Symbol()]: 'symbol' }; * for (const key of ex(obj).keys()) { * console.log(obj[key]); // No type error * } * ``` * * @see {@link Object.keysS} */ keys: () => StrictKeys; /** * Returns an array of values of the enumerable properties of the object (using `Object.valuesS`). * * @example * ```typescript * const obj = { a: 1, b: 2, c: 3, 5: 42, [Symbol()]: 'symbol' }; * ex(obj).values(); // => [42, 1, 2, 3] * const values = ex(obj).values(); // values :: number[] * ``` * * @see {@link Object.valuesS} */ values: () => StrictValues; /** * Returns an array of key/values of the enumerable properties of the object (using `Object.entriesS`). * * @example * ```typescript * const obj = { a: 1, b: 2, c: true, 5: 42, [Symbol()]: 'symbol' }; * ex(obj).entries(); // => [['5', 42], ['a', 1], ['b', 2], ['c', true]] * const entries = ex(obj).entries(); // entries :: (['5', number] | ['a', number] | ['b', number] | ['c', boolean])[] * ``` * * @see {@link Object.entriesS} */ entries: () => StrictEntries; /** * Returns the number of enumerable properties and methods of the object or the length of the object if it is an array-like object (using `Object.size`) * * @example * ```typescript * ex({ a: 1, b: 2, c: 3 }).size(); // => 3 * ex({ length: 3 }).size(); // => 3 * ex(new Map([['a', 1], ['b', 2], ['c', 3]])).size(); // => 3 * ex(new Set([1, 2, 3, 4])).size(); // => 4 * ``` */ size: () => Size; /** * Returns `true` if the object is an empty object. An object is considered empty unless it’s an arguments object, array, or * jQuery-like collection with a length greater than 0 or an object with own enumerable properties. * * @example * ```typescript * ex({}).isEmpty(); // => true * ex({ a: 1 }).isEmpty(); // => false * ex([1, 2, 3]).isEmpty(); // => false * ex([]).isEmpty(); // => true * ex(new Map()).isEmpty(); // => true * ex(new Set()).isEmpty(); // => true * ``` */ isEmpty: () => boolean; /** * Calls a defined callback function on each enumerable key/value pair of the object, and returns an object that contains the results. * @param callbackfn A function that accepts up to three arguments. The map function calls the callbackfn function one time for each key/value pair in the object. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. * * @example * ```typescript * const obj = { a: 1, b: 2, 5: 42, [Symbol()]: 'symbol' }; * ex(obj).map(([key, value]) => [`${key}_`, value * 2]); // => { '5_': 84, 'a_': 2, 'b_': 4 } * const mapped = ex(obj).map(([key, value]) => [`${key}_`, value * 2]); // mapped :: { '5_': number, 'a_': number, 'b_': number } * ``` */ map: ( callbackfn: ( entry: StrictEntries[number], index: number, object: O, ) => R, thisArg?: any, ) => ExtendedObject<{ [P in R[0]]: R[1]; }>; /** * Calls a defined callback function on each enumerable key of the object, and returns an object that contains the results. * @param callbackfn A function that accepts up to three arguments. The mapKeys function calls the callbackfn function one time for each key in the object. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. * * @example * ```typescript * const obj = { a: 1, b: 2, 5: 42, [Symbol()]: 'symbol' }; * ex(obj).mapKey((key) => `${key}_`); // => { '5_': 42, 'a_': 1, 'b_': 2 } * const mapped = ex(obj).mapKeys((key) => `${key}_`); // mapped :: { '5_': number, 'a_': number, 'b_': number } * ``` */ mapKeys: ( callbackfn: (key: StrictKeys[number], index: number, object: O) => R, thisArg?: any, ) => ExtendedObject<{ [P in R]: StrictValues[number]; }>; /** * Calls a defined callback function on each enumerable value of the object, and returns an object that contains the results. * @param callbackfn A function that accepts up to three arguments. The mapValues function calls the callbackfn function one time for each value in the object. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. * * @example * ```typescript * const obj = { a: 1, b: 2, 5: 42, [Symbol()]: 'symbol' }; * ex(obj).mapValues((value) => value * 2); // => { '5': 84, 'a': 2, 'b': 4 } * const mapped = ex(obj).mapValues((value) => value * 2); // mapped :: { '5': number, 'a': number, 'b': number } * ``` */ mapValues: ( callbackfn: (value: StrictValues[number], index: number, object: O) => R, thisArg?: any, ) => ExtendedObject<{ [P in StrictKeys[number]]: R; }>; /** * Calls a defined callback function on each enumerable key/value pair of the object, and returns an object that contains results meeting the condition specified in the callback function. * @param predicate A function that accepts up to three arguments. The filter function calls the predicate function one time for each key/value pair in the object. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. * * @example * ```typescript * const obj = { a: 1, b: 2, 5: 42, [Symbol()]: 'symbol' }; * ex(obj).filter(([key, value]) => key === 'a' || value === 42); // => { 5: 42, a: 1 } * const filtered = ex(obj).filter(([key, value]) => key === 'a' || value === 42); // filtered :: { 5?: number | undefined, a?: number | undefined, b?: number | undefined } * ``` */ filter: ( predicate: ( entry: StrictEntries[number], index: number, object: O, ) => boolean, thisArg?: any, ) => ExtendedObject<{ [P in StrictKeys[number]]?: O[P]; }>; /** * Calls a defined callback function on each enumerable key/value pair of the object. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduce function calls the callbackfn function one time for each key/value pair in the object. * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an object value. * * @example * ```typescript * const obj = { a: 1, b: 2, c: 3 }; * ex(obj).reduce((acc, [key, value]) => acc + value, 0); // => 6 * ``` */ reduce: { ( callbackfn: ( previousValue: StrictValues[number], currentEntry: StrictEntries[number], currentIndex: number, object: O, ) => StrictValues[number], ): StrictValues[number]; ( callbackfn: ( previousValue: R, currentEntry: StrictEntries[number], currentIndex: number, object: O, ) => R, initialValue: R, ): R; }; /** * Returns an object composed of the own and inherited enumerable properties of the object that are not omitted. * @param keys The property names or paths to omit. * * @example * ```typescript * const obj = { a: 1, b: 2, c: { d: [3, 4, 5] }, e: 6 }; * ex(obj).omit('a', 'b'); // => { c: { d: [3, 4, 5] }, e: 6 } * ex(obj).omit(path('c.d')); // => { a: 1, b: 2, c: {}, e: 6 } * ex(obj).omit(prop('e'), 'a', path('c.d[1]')); // => { b: 2, c: { d: [3, 5] } } * ``` */ omit: < const P extends keyof O | typeof omitPropFallback, const PP extends BasePath | BasePathArray = never, >( ...keys: readonly (P | PropFn | PathFn)[] ) => ExtendedObject< [PP] extends [never] ? typeof omitPropFallback extends P ? O : Omit : OmitByPath, PP> >; /** * Returns an object composed of keys generated from the results of running each element of the object through `fn`. * The corresponding value of each key is an array of the elements responsible for generating the key. * @param fn Prop, Path, a property name or a function that accepts up to three arguments. The groupBy function calls the fn function one time for each key/value pair in the object. * * @example * ```typescript * const obj = { a: 1, b: 2, 5: 42 }; * const obj2 = { a: { value: 1, nested: { v: 1 } }, b: { value: 2, nested: { v: 2 } }, c: { value: 2, nested: { v: 3 } } }; * ex(obj).groupBy(([, value]) => value % 2 === 0 ? 'even' : 'odd'); // => { odd: [1], even: [42, 2] } * ex(obj2).groupBy('value'); // => { 1: [{ value: 1, nested: { v: 1 } }], 2: [{ value: 2, nested: { v: 2 } }, { value: 2, nested: { v: 3 } }] } * ex(obj2).groupBy(prop('value')); // => { 1: [{ value: 1, nested: { v: 1 } }], 2: [{ value: 2, nested: { v: 2 } }, { value: 2, nested: { v: 3 } }] } * ex(obj2).groupBy(path('nested.v')); // => { 1: [{ value: 1, nested: { v: 1 } }], 2: [{ value: 2, nested: { v: 2 } }], 3: [{ value: 2, nested: { v: 3 } }] } * ``` */ groupBy: { < const K extends { [P in keyof O[keyof O]]: O[keyof O][P] extends PropertyKey ? P : never; }[keyof O[keyof O]], const PP extends BasePath | BasePathArray = never, >( fn: K | PropFn | PathFn, ): ExtendedObject< ListOf['length'] extends 1 ? { [P in Cast]: O[keyof O]; } : GetByPath extends PropertyKey ? { [P in Cast, PropertyKey>]: O[keyof O]; } : never >; ( fn: (entry: StrictEntries[number], index: number, object: O) => R, ): ExtendedObject<{ [P in R]: O[keyof O]; }>; }; with: { /** * Returns a new object with the specified property set to the given value. * @param prop Property name or `prop` function representing the property to set. * @param value Value to set. * * @example * ```typescript * const obj = { a: 1, b: 2, c: { d: [{ e: 3 }] } }; * ex(obj).with('a', 2); // => { a: 2, b: 2, c: { d: [{ e: 3 }] } } * ex(obj).with(prop('a'), 2); // => { a: 2, b: 2, c: { d: [{ e: 3 }] } } * ex(obj).with(path('c.d[0].e'), 4); // => { a: 1, b: 2, c: { d: [{ e: 4 }] } } * ex(obj).with(['c', 'd', '0', 'e'], 4); // => { a: 1, b: 2, c: { d: [{ e: 4 }] } } * ``` */ < const K extends { [P in keyof O]: O[P] extends PropertyKey ? P : never; }[keyof O], >( prop: K | PropFn, value: O[K], ): ExtendedObject; /** * Returns a new object with the specified property set to the given value. * @param path Property path or `path` function representing the property to set. * @param value Value to set. * * @example * ```typescript * const obj = { a: 1, b: 2, c: { d: [{ e: 3 }] } }; * ex(obj).with('a', 2); // => { a: 2, b: 2, c: { d: [{ e: 3 }] } } * ex(obj).with(prop('a'), 2); // => { a: 2, b: 2, c: { d: [{ e: 3 }] } } * ex(obj).with(path('c.d[0].e'), 4); // => { a: 1, b: 2, c: { d: [{ e: 4 }] } } * ex(obj).with(['c', 'd', '0', 'e'], 4); // => { a: 1, b: 2, c: { d: [{ e: 4 }] } } * ``` */ | BasePathArray>( path: PathFn, value: Obj.Get extends List ? Path : never>, ): ExtendedObject; /** * Returns a new object with the specified property set to the given value. * @param path Property path or `path` function representing the property to set. * @param value Value to set. * * @example * ```typescript * const obj = { a: 1, b: 2, c: { d: [{ e: 3 }] } }; * ex(obj).with('a', 2); // => { a: 2, b: 2, c: { d: [{ e: 3 }] } } * ex(obj).with(prop('a'), 2); // => { a: 2, b: 2, c: { d: [{ e: 3 }] } } * ex(obj).with(path('c.d[0].e'), 4); // => { a: 1, b: 2, c: { d: [{ e: 4 }] } } * ex(obj).with(['c', 'd', '0', 'e'], 4); // => { a: 1, b: 2, c: { d: [{ e: 4 }] } } * ``` */ >( path: PP, value: Obj.Get extends List ? Path : never>, ): ExtendedObject; }; withW: { /** * Returns a new object with the specified property set to the given value. * * It is the same as `ExtendedObject#with`, but with looser type restrictions. The `W` postfix stands for "wide". * @param prop Property name or `prop` function representing the property to set. * @param value Value to set. * * @example * ```typescript * const obj = { a: 1, b: 2, c: { d: [{ e: 3 }] } }; * ex(obj).withW('a', 2); // => { a: 2, b: 2, c: { d: [{ e: 3 }] } } * ex(obj).withW(prop('a'), 2); // => { a: 2, b: 2, c: { d: [{ e: 3 }] } } * ex(obj).withW(path('c.d[0].e'), 4); // => { a: 1, b: 2, c: { d: [{ e: 4 }] } } * ex(obj).withW(['c', 'd', '0', 'e'], 4); // => { a: 1, b: 2, c: { d: [{ e: 4 }] } } * ``` * * @see {@link ExtendedObject#with} */ ( prop: K | PropFn, value: V, ): Obj.With>; /** * Returns a new object with the specified property set to the given value. * * It is the same as `ExtendedObject#with`, but with looser type restrictions. The `W` postfix stands for "wide". * @param path Property path or `path` function representing the property to set. * @param value Value to set. * * @example * ```typescript * const obj = { a: 1, b: 2, c: { d: [{ e: 3 }] } }; * ex(obj).withW('a', 2); // => { a: 2, b: 2, c: { d: [{ e: 3 }] } } * ex(obj).withW(prop('a'), 2); // => { a: 2, b: 2, c: { d: [{ e: 3 }] } } * ex(obj).withW(path('c.d[0].e'), 4); // => { a: 1, b: 2, c: { d: [{ e: 4 }] } } * ex(obj).withW(['c', 'd', '0', 'e'], 4); // => { a: 1, b: 2, c: { d: [{ e: 4 }] } } * ``` * * @see {@link ExtendedObject#with} */ ( path: PathFn, value: V, ): Obj.With, Obj.WritableDeep>; /** * Returns a new object with the specified property set to the given value. * * It is the same as `ExtendedObject#with`, but with looser type restrictions. The `W` postfix stands for "wide". * @param path Property path or `path` function representing the property to set. * @param value Value to set. * * @example * ```typescript * const obj = { a: 1, b: 2, c: { d: [{ e: 3 }] } }; * ex(obj).withW('a', 2); // => { a: 2, b: 2, c: { d: [{ e: 3 }] } } * ex(obj).withW(prop('a'), 2); // => { a: 2, b: 2, c: { d: [{ e: 3 }] } } * ex(obj).withW(path('c.d[0].e'), 4); // => { a: 1, b: 2, c: { d: [{ e: 4 }] } } * ex(obj).withW(['c', 'd', '0', 'e'], 4); // => { a: 1, b: 2, c: { d: [{ e: 4 }] } } * ``` * * @see {@link ExtendedObject#with} */ ( path: PP, value: V, ): Obj.With, Obj.WritableDeep>; }; }; /** * Creates an object with additional methods. * @param o The object to extend. * * @example * ```typescript * const obj = { a: 1, b: 2, c: 3 }; * ex(obj).filter(([k, v]) => v % 2 === 0).mapKeys((k) => k.toUpperCase()); // => { B: 2 } * ex(obj).omit('a', 'b').size(); // => 1 * ``` */ export declare const ex: (o: O) => ExtendedObject; export { default as groupBy } from './groupBy.js'; //# sourceMappingURL=index.d.ts.map