import { IsArrayStrict, Prettify } from "../helpers"; import { Call, Fn, PartialApply, unset, _ } from "../core/Core"; import { Std } from "../std/Std"; import { Strings } from "../strings/Strings"; import * as Impl from "./impl/objects"; export declare namespace Objects { /** * Create an object from a union of `[key, value]` entries. * @param entries - union of entries to convert to an object * @returns an object * @example * ```ts * type T0 = Call; // { a: 1; b: true } * ``` */ export interface FromEntries extends Fn { return: Impl.FromEntries>; } /** * Turn an object into a union of entries * @param obj - The object to transform to entries * @returns a union of `[key, value]` entry tuples. * @example * ```ts * type T0 = Call; // ["a", 1] | ["b", true] * ``` */ export interface Entries extends Fn { return: Impl.Entries; } type MapValuesImpl = { [K in keyof T]: Call; }; /** * Map over values in an object type. * @param fn - The function to run on every object value * @param obj - The object to transform * @returns a new object with updated values * @example * ```ts * type T0 = Call< * Objects.MapValues, * { a: "1"; b: "2" } * >; // { a: 1, b: 2 } * ``` */ export interface MapValues extends Fn { return: MapValuesImpl; } type MapKeysImpl = { [K in keyof T as Extract, PropertyKey>]: T[K]; }; /** * Map over keys in an object type. * @param fn - The function to run on every object key * @param obj - The object to transform * @returns a new object with updated keys * @example * ```ts * type T0 = Call< * Objects.MapKeys, * { a: 1; b: 2 } * >; // { A: 1, B: 2 } * ``` */ export interface MapKeys extends Fn { return: MapKeysImpl; } /** * Turn object keys into kebab-case * @param obj - The object to transform * @returns a new object with updated keys * @example * ```ts * type T0 = Call< * Objects.KebabCase, * { userName: "Bob" } * >; // { "user-name": "Bob" } * ``` */ export interface KebabCase extends Fn { return: Call, this["arg0"]>; } /** * Turn object keys into snake_case * @param obj - The object to transform * @returns a new object with updated keys * @example * ```ts * type T0 = Call< * Objects.SnakeCase, * { userName: "Bob" } * >; // { user_name: "Bob" } * ``` */ export interface SnakeCase extends Fn { return: Call, this["arg0"]>; } /** * Turn object keys into camelCase * @param obj - The object to transform * @returns a new object with updated keys * @example * ```ts * type T0 = Call< * Objects.CamelCase, * { user_name: "Bob" } * >; // { userName: "Bob" } * ``` */ export interface CamelCase extends Fn { return: Call, this["arg0"]>; } type MapKeysDeepImpl = IsArrayStrict extends true ? MapKeysDeepImpl[number], fn>[] : T extends object ? { [K in keyof T as Extract, PropertyKey>]: Prettify>; } : T; /** * Recursively transform all keys in a structure of object types * @param fn - The function to apply to every key * @param obj - The object to transform * @returns a new object with updated keys * @example * ```ts * type T0 = Call< * Objects.MapKeysDeep>, * { a: { b: { c: string } } } * >; // { _a: { _b: { _c: string } } } * ``` */ export interface MapKeysDeep extends Fn { return: MapKeysDeepImpl; } /** * Recursively transform all keys of a deeply nested object * to kebab-case. * @param obj - The object to transform * @returns a new object with updated keys * @example * ```ts * type T0 = Call< * Objects.KebabCaseDeep, * { currentUser: { firstName: string } } * >; // { "current-user": { "first-name": string } } * ``` */ export interface KebabCaseDeep extends Fn { return: Call, this["arg0"]>; } /** * Recursively transform all keys of a deeply nested object * to snake_case. * @param obj - The object to transform * @returns a new object with updated keys * @example * ```ts * type T0 = Call< * Objects.SnakeCaseDeep, * { currentUser: { firstName: string } } * >; // { current_user: { first_name: string } } * ``` */ export interface SnakeCaseDeep extends Fn { return: Call, this["arg0"]>; } /** * Recursively transform all keys of a deeply nested object * to camelCase. * @param obj - The object to transform * @returns a new object with updated keys * @example * ```ts * type T0 = Call< * Objects.CamelCaseDeep, * { current_user: { first_name: string } } * >; // { currentUser: { firstName: string } } * ``` */ export interface CamelCaseDeep extends Fn { return: Call, this["arg0"]>; } /** * Only keep keys of an object if they are * assignable to some type. * @param key - The type remaining keys should be assignable to * @param obj - The object to filter * @returns a filtered object * @example * ```ts * type T0 = Call< * Objects.Pick<"a" | "b">, * { a: 1, b: 1, c: 1 } * >; // { a: 1, b: 1 } * ``` */ export type Pick = PartialApply; interface PickFn extends Fn { return: PickImpl; } type PickImpl = { [key in Extract]: obj[key]; }; /** * Only keep keys of an object if they aren't * assignable to some type. * @param key - The type remaining keys should _not_ be assignable to * @param obj - The object to filter * @returns a filtered object * @example * ```ts * type T0 = Call< * Objects.Pick<"a" | "b">, * { a: 1, b: 1, c: 1 } * >; // { c: 1 } * ``` */ export type Omit = PartialApply; interface OmitFn extends Fn { return: OmitImpl; } type OmitImpl = { [key in Exclude]: obj[key]; }; /** * Only keep keys of an object if the predicate function * returns true * @param fn - The predicate function, taking (value, key) as arguments * @param obj - The object to filter * @returns a filtered object * @example * ```ts * type T0 = Call< * Objects.PickBy>, * { a: "ab", b: "ac", c: "bc" } * >; // { a: "ab", b: "ac" } * ``` */ export interface PickBy extends Fn { return: PickByImpl; } type PickByImpl = Impl.FromEntries, fn>>; type PickEntriesImpl = entries extends any ? Call extends true ? entries : never : never; /** * Only keep keys of an object if the predicate function * returns false * @param fn - The predicate function, taking (value, key) as arguments * @param obj - The object to filter * @returns a filtered object * @example * ```ts * type T0 = Call< * Objects.PickBy>, * { a: "ab", b: "ac", c: "bc" } * >; // { c: "bc" } * ``` */ export interface OmitBy extends Fn { return: OmitByImpl; } type OmitByImpl = Impl.FromEntries, fn>>; type OmitEntriesImpl = entries extends any ? Call extends true ? never : entries : never; /** * Merge several objects together * @param {...objects} - Objects to merge * @returns a merged object * @example * ```ts * type T0 = Call, { b: number }>; // { a: string, b: number } * type T1 = Call>; // { a: string, b: number } * type T2 = Call>; // { a: 1, b: 1, c: 1 } * ``` */ export type Assign = PartialApply; interface AssignFn extends Fn { return: Impl.Assign; } /** * Make all properties of an object readonly * @description This function is used to make properties of an object readonly * @param value - The object to make properties readonly * @returns The object with its properties made readonly * @example * ```ts * type T0 = Call; // { readonly a:1; readonly b: true} * type T1 = Call>; // { readonly a:1; readonly b: true} * ``` */ export type Readonly = PartialApply; interface ReadonlyFn extends Fn { return: this["args"] extends [infer value] ? Std._Readonly : never; } /** * Make all properties of an object required * @description This function is used to make properties of an object required * @param value - The object to make properties required * @returns The object with its properties made required * @example * ```ts * type T0 = Call; // { a:1; b: true} * type T1 = Call>; // { a:1; b: true} * ``` */ export type Required = PartialApply; interface RequiredFn extends Fn { return: this["args"] extends [infer value] ? Std._Required : never; } /** * Make all properties of an object optional * @description This function is used to make properties of an object optional * @param value - The object to make properties optional * @returns The object with its properties made optional * @example * ```ts * type T0 = Call; // { a?:1; b?: true} * type T1 = Call>; // { a?:1; b?: true} * ``` */ export type Partial = PartialApply; interface PartialFn extends Fn { return: this["args"] extends [infer value] ? Std._Partial : never; } /** * Make all properties of an object mutable * @param value - The object to make properties mutable * @returns The object with its properties made mutable * @example * ```ts * type T0 = Call; // { a:1; b: true } * ``` */ export type Mutable = PartialApply; interface MutableFn extends Fn { return: this["args"] extends [infer obj, ...any] ? { -readonly [key in keyof obj]: obj[key]; } : never; } /** * Makes all levels of an object optional * @description This function is used to make all levels of an object optional * @param obj - The object to make levels optional * @returns The object with its levels made optional * * @example * ```ts * type T0 = Call; * // ^? { a?:1; b?: true} * type T1 = Call; * // ^? { a?:1; b?: { c?: true } } * type T2 = Call; * // ^? { a?:1; b?: { c?: true, d?: { e?: false } } } */ export type PartialDeep = PartialApply; interface PartialDeepFn extends Fn { return: this["args"] extends [infer obj] ? Impl.TransformObjectDeep : never; } /** * Makes all levels of an object required * @description This function is used to make all levels of an object required * @param obj - The object to make levels required * @returns The object with its levels made required * * @example * ```ts * type T0 = Call; * // ^? { a: 1; b: true } * type T1 = Call; * // ^? { a: 1; b: { c: true } } * type T2 = Call; * // ^? { a: 1; b: { c: true, d: { e: false } } } */ export type RequiredDeep = PartialApply; interface RequiredDeepFn extends Fn { return: this["args"] extends [infer obj] ? Impl.TransformObjectDeep : never; } /** * Makes all levels of an object readonly * @description This function is used to make all levels of an object readonly * @param obj - The object to make levels readonly * @returns The object with its levels made readonly * * @example * ```ts * type T0 = Call; * // ^? { readonly a: 1; readonly b: true } * type T1 = Call; * // ^? { readonly a: 1; readonly b: { readonly c: true } } * type T2 = Call; * // ^? { readonly a: 1; readonly b: { readonly c: true, d: { readonly e: false } } } */ export type ReadonlyDeep = PartialApply; interface ReadonlyDeepFn extends Fn { return: this["args"] extends [infer obj] ? Impl.TransformObjectDeep : never; } /** * Makes all levels of an object mutable * @description This function is used to make all levels of an object mutable * @param obj - The object to make levels mutable * @returns The object with its levels made mutable * * @example * ```ts * type T0 = Call; * // ^? { a:1; b: true } * type T1 = Call; * // ^? { a:1; b: { c: true } } * type T2 = Call; * // ^? { a:1; b: { c: true, d: { e: false } } } */ export type MutableDeep = PartialApply; interface MutableDeepFn extends Fn { return: this["args"] extends [infer obj] ? Impl.TransformObjectDeep : never; } /** * Get a value within an object or a tuple type. * @description This function takes an object, a path to one of its properties, * and returns the property under that path. * @param path - the path to the property to get. * @param obj - the object to read from. * @returns The value under that path * * @example * ```ts * type T0 = Call, { a: 1, b: 1 }>; // 1 * type T1 = Call, { a: [1, 2, 3] }>; // 1 * type T2 = Call, { a: { b: 1 }, c: '' }>; // 1 * ``` */ export type Get = PartialApply; export interface GetFn extends Fn { return: this["args"] extends [ infer path extends string | number, infer obj, ...any ] ? Impl.GetFromPath : never; } /** * Updates an object or a tuple type. * @description This function takes an object, a path to one of its properties, * a new value or a function to apply to this property, and returns a new version * of this object with this property updated. * @param path - the path to the property to update * @param valueOrFn - a value to set, or a function to apply on the target property * @param obj - the object to update. * @returns The updated object. * * @example * ```ts * type T0 = Call>, { a: 1, b: 1 }>; // { a: 2, b: 1 } * type T1 = Call, { a: [1, 2, 3] }>; // { a: [4, 2, 3] } * type T2 = Call>, { a: { b: 1 }, c: '' }>; // { a: { b: 2 }, c: '' } * type T3 = Call, { a: { b: 1 } }>; // { a: { b: "Hello" } } * ``` */ export type Update = PartialApply; export interface UpdateFn extends Fn { return: this["args"] extends [ infer path extends string | number, infer fnOrValue, infer obj, ...any ] ? Impl.Update : never; } /** * Create an object from parameters * @description This function is used to make an object from parameters * And allows to place the parameters in any object property * @param args - The parameters to make the object from * @returns The object made from the parameters * * @example * ```ts * type T0 = Apply, [1, 2]>; // { a: 1, b: 2 } * ``` */ interface CreateFn extends Fn { return: this["args"] extends [infer pattern, ...infer args] ? Impl.Create : never; } export type Create = PartialApply; interface RecordFn extends Fn { return: this["args"] extends [infer union extends string, infer value] ? Std._Record : never; } /** * Create a record from a union of strings and a value type * @description This function is used to create a record from a union of strings * @param union - The union of strings to create the record from * @param value - The value to assign to each property * @returns The record created from the union of strings * * @example * ```ts * type T0 = Call, 1>; // { a: 1, b: 1, c: 1 } * ``` */ export type Record = PartialApply; /** * Smarter version of keyof that also works with tuples * @params args[0] - The type to extract keys from * @returns An union of all the types's keys * @example * ```ts * type T0 = Call; // 0 | 1 | 2 * ``` */ export interface Keys extends Fn { return: Impl.Keys; } /** * Smarter version of Values that also works with tuples * @params args[0] - The type to extract values from * @returns An union of all the types's values * @example * ```ts * type T0 = Call; // 'a' | 'b' | 'c' * ``` */ export interface Values extends Fn { return: Impl.Values; } /** * Create a union of all deep paths the object has * @description This function is used to create a union from an object with keys * @param obj - The object from which the union will be generated * @returns An union with all the possible deep paths * * @example * ```ts * type T0 = Call; // 'a' | 'a.b' * ``` */ export interface AllPaths extends Fn { return: Impl.AllPaths; } export {}; }