From 0bab704163c143dd981d81aef42bda86a657af02 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Tue, 21 Oct 2025 15:01:19 +0700 Subject: [PATCH] chore(FE-113): create getByPath helper function --- src/lib/helper.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/lib/helper.ts b/src/lib/helper.ts index d85b7b16..0f827e8a 100644 --- a/src/lib/helper.ts +++ b/src/lib/helper.ts @@ -27,3 +27,37 @@ export const formatCurrency = ( maximumFractionDigits, }).format(value); }; + +/** + * Retrieves a nested value from an object using a dot-delimited key path. + * Supports array indexes (e.g., "users.0.name") and returns a default value + * if the path does not exist. + * + * @param obj - The source object to search. + * @param path - Dot-delimited key string (e.g., "user.address.city"). + * @param defaultValue - Optional value to return if the key path is not found. + * @returns The value found at the specified path, or the default value. + */ +export function getByPath( + obj: T, + path: string, + defaultValue?: D +): unknown | D { + if (obj == null) return defaultValue as D; + if (!path) return obj as unknown; + + const segments = path.split('.').filter(Boolean); + let cur: { [key: string]: unknown } = obj; + + for (const seg of segments) { + if (cur == null) return defaultValue as D; + const key: string | number = + Array.isArray(cur) && /^\d+$/.test(seg) ? Number(seg) : seg; + if (Object(cur) !== cur || !(key in cur)) { + return defaultValue as D; + } + cur = cur[key] as { [key: string]: unknown }; + } + + return cur as unknown; +}