import type { ValueWithUndefinedForIndexSignatures } from '../map/index.js' type ConcatPath = T extends '' ? P : `${T}.${P}` type Length = T extends { length: infer L } ? L : never type BuildTuple = T extends { length: L } ? T : BuildTuple type Subtract = BuildTuple extends [...infer U, ...BuildTuple] ? Length : never export type AllPaths< T, P extends string = '', MaxDepth extends number = 10 > = T extends (infer U)[] ? | `${P}[${number}]` | AllPaths> | P : T extends BaseDeepMap ? MaxDepth extends 0 ? never : { [K in keyof T]-?: K extends number | string ? | AllPaths, Subtract> | (P extends '' ? never : P) : never }[keyof T] : P type IsNumber = T extends `${number}` ? true : false type ElementType = T extends (infer U)[] ? U : never type Unwrap = P extends `[${infer I}]${infer R}` ? [ElementType, IsNumber] extends [infer Item, true] ? R extends '' ? Item : Unwrap : never : never type NestedObjKey = P extends `${infer A}.${infer B}` ? A extends keyof T ? FromPath, B> : never : never type NestedObjKeyWithIndexSignatureUndefined = P extends `${infer A}.${infer B}` ? A extends keyof T ? FromPathWithIndexSignatureUndefined, B> : never : never type NestedArrKey = P extends `${infer A}[${infer I}]${infer R}` ? [A, NonNullable]>, IsNumber] extends [ keyof T, (infer Item)[], true ] ? R extends '' ? Item : R extends `.${infer NewR}` ? FromPath : R extends `${infer Indices}.${infer MoreR}` ? FromPath, MoreR> : Unwrap : never : never export type FromPath = T extends unknown ? NestedArrKey extends never ? NestedObjKey extends never ? P extends keyof T ? T[P] : never : NestedObjKey : NestedArrKey : never export type FromPathWithIndexSignatureUndefined = T extends unknown ? NestedArrKey extends never ? NestedObjKeyWithIndexSignatureUndefined extends never ? P extends keyof T ? ValueWithUndefinedForIndexSignatures : never : NestedObjKeyWithIndexSignatureUndefined : NestedArrKey : never export type BaseDeepMap = Record /** * Get a value by object path. `undefined` if key is missing. * * ``` * import { getPath } from 'nanostores' * * getPath({ a: { b: { c: ['hey', 'Hi!'] } } }, 'a.b.c[1]') // Returns 'Hi!' * ``` * * @param obj Any object. * @param path Path splitted by dots and `[]`. Like: `props.arr[1].nested`. * @returns The value for this path. Undefined if key is missing. */ export function getPath>( obj: T, path: K ): FromPath /** * Set a deep value by path. Copies are made at each level of `path` so that no * part of the original object is mutated (but it does not do a full deep copy * -- some sub-objects may still be shared between the old value and the new * one). Sparse arrays will be created if you set arbitrary length. * * ``` * import { setPath } from 'nanostores' * * setPath({ a: { b: { c: [] } } }, 'a.b.c[1]', 'hey') * // Returns `{ a: { b: { c: [, 'hey'] } } }` * ``` * * @param obj Any object. * @param path Path splitted by dots and `[]`. Like: `props.arr[1].nested`. * @returns The new object. */ export function setPath>( obj: T, path: K, value: FromPath ): T /** * Set a deep value by key. Copies are made at each level of `path` so that no * part of the original object is mutated (but it does not do a full deep copy * -- some sub-objects may still be shared between the old value and the new * one). Sparse arrays will be created if you set arbitrary length. * * ``` * import { setByKey } from 'nanostores' * * setByKey({ a: { b: { c: [] } } }, ['a', 'b', 'c', 1], 'hey') * // Returns `{ a: { b: { c: [, 'hey'] } } }` * ``` * * @param obj Any object. * @param splittedKeys An array of keys representing the path to the value. * @param value New value. * @retunts The new object. */ export function setByKey( obj: T, splittedKeys: PropertyKey[], value: unknown ): T