@cloudcome/utils-core
Version:
cloudcome core utils
112 lines (111 loc) • 4.6 kB
TypeScript
import { AnyArray, AnyObject } from '../types';
type Idx<T, K> = K extends keyof T ? T[K] : number extends keyof T ? K extends `${number}` ? T[number] : never : never;
type Join<K, P> = K extends string | number ? P extends string | number ? `${K}${'' extends P ? '' : '.'}${P}` : never : never;
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...0[]];
export type ObjectPath<O, D extends number = 4> = [D] extends [never] ? never : O extends object ? {
[K in keyof O]-?: K extends string | number ? `${K}` | Join<K, ObjectPath<O[K], Prev[D]>> : never;
}[keyof O] : '';
export type ObjectLeafPath<O, D extends number = 4> = [D] extends [never] ? never : O extends object ? {
[K in keyof O]-?: K extends string | number ? O[K] extends string | number ? `${K}` | Join<K, ObjectLeafPath<O[K], Prev[D]>> : Join<K, ObjectLeafPath<O[K], Prev[D]>> : never;
}[keyof O] : '';
export type ObjectPathValue<O, P extends ObjectPath<O, 4>> = P extends `${infer Key}.${infer Rest}` ? Rest extends ObjectPath<Idx<O, Key>, 4> ? ObjectPathValue<Idx<O, Key>, Rest> : never : Idx<O, P>;
/**
* 表示对象节点的信息。
*
* @template V - 键值的类型。
*/
export type ObjectNode<V = unknown | undefined> = {
/**
* 当前节点的父级对象。
*/
parent: unknown | undefined;
/**
* 当前节点的键名路径。
*/
keys: string[];
/**
* 当前节点的键名。
*/
key: string | undefined;
/**
* 当前节点的键值。
*/
value: V;
};
/**
* 根据属性路径获取属性值
* @param {O} obj
* @param {string | string[] | P} path
* @returns {ObjectNode<O>}
* 根据属性路径获取属性值。
*
* @template O - 目标对象的类型。
* @template P - 属性路径的类型。
* @param {O} obj - 要操作的目标对象。
* @param {P | string | string[]} path - 属性路径,可以是字符串或字符串数组。支持点分隔符(如 "a.b.c")或数组形式(如 ["a", "b", "c"])。
* @returns {ObjectNode<O>} 返回一个包含父级、键名路径、键名和键值的对象节点。
*
* @example
* ```typescript
* const obj = { a: { b: { c: 42 } } };
* const result = objectGet(obj, 'a.b.c');
* console.log(result.value); // 输出 42
* ```
*/
export declare function objectGet<O extends AnyObject, P extends ObjectPath<O>>(obj: O, path: P | string | string[]): ObjectNode<O>;
/**
* 配置选项,用于控制 `objectSet` 的行为。
*
* @template O - 目标对象的类型。
*/
export type ObjectSetOptions<O extends AnyObject> = {
/**
* 在设置值之前调用的钩子函数。
* 如果返回 `false`,则阻止设置值。
*
* @param {ObjectNode<O> & { key: string }} node - 当前节点信息。
* @returns {boolean | undefined | void} 返回 `false` 时阻止设置值。
*/
beforeSet(node: ObjectNode<O> & {
key: string;
}): boolean | undefined | void;
/**
* 当遇到未定义的中间节点时调用的钩子函数。
* 返回值将用于创建中间节点。
*
* @param {ObjectNode<O>} node - 当前节点信息。
* @returns {AnyObject | AnyArray | undefined | void} 返回值将用于创建中间节点。
*/
undefinedSet(node: ObjectNode<O>): AnyObject | AnyArray | undefined | void;
};
/**
* 根据属性路径设置属性值
* @param {AnyObject} obj
* @param {string} path
* @param {V} val
* @param {Partial<ObjectSetOptions<O>>} options
* @returns {ObjectNode<O, V>}
* 根据属性路径设置属性值。
*
* @template O - 目标对象的类型。
* @template V - 要设置的值的类型。
* @param {O} obj - 要操作的目标对象。
* @param {string | string[]} path - 属性路径,可以是字符串或字符串数组。支持点分隔符(如 "a.b.c")或数组形式(如 ["a", "b", "c"])。
* @param {V} val - 要设置的值。
* @param {Partial<ObjectSetOptions<O>>} [options] - 可选配置项,用于控制设置行为。
* @returns {ObjectNode<V>} 返回一个包含父级、键名路径、键名和键值的对象节点。
*
* @example
* ```typescript
* const obj = {};
* objectSet(obj, 'a.b.c', 42);
* console.log(obj); // 输出 { a: { b: { c: 42 } } }
*
* objectSet(obj, 'a.b.c', 100, {
* beforeSet: (node) => node.key === 'c',
* });
* console.log(obj); // 输出 { a: { b: { c: 100 } } }
* ```
*/
export declare function objectSet<O extends AnyObject, V>(obj: O, path: string | string[], val: V, options?: Partial<ObjectSetOptions<O>>): ObjectNode<V>;
export {};