UNPKG

@modern-kit/utils

Version:
1 lines 6.01 kB
{"version":3,"file":"index.mjs","sources":["../../../src/object/set/index.ts"],"sourcesContent":["import type { PropertyPath, GetByPath } from '@modern-kit/types';\nimport { cloneDeep } from '../../common/cloneDeep';\nimport { hasProperty } from '../../validator/hasProperty';\nimport { isNil } from '../../validator/isNil';\nimport { get } from '../get';\n\n/**\n * @description 객체의 특정 경로를 업데이트하고 새로운 객체를 반환합니다.\n *\n * 점 표기법(dot notation)을 사용하여 중첩된 객체의 깊은 속성에 접근할 수 있습니다.\n * 주어진 객체의 타입에 옵셔널 프로퍼티가 있는 경우, 옵셔널(?) 경로로 접근해야 합니다.\n *\n * immutable 옵션을 true로 설정하면, 원본 객체를 수정하지 않고 새로운 객체를 반환합니다.\n *\n * @template T - 업데이트할 객체의 타입\n * @template P - 업데이트할 경로의 타입\n * @template V - 업데이트할 값의 타입\n *\n * @param {T} obj - 업데이트할 객체\n * @param {P} path - 업데이트할 경로\n * @param {V} value - 업데이트할 값\n * @param {boolean} [options.immutable=false] - true일 경우, 원본 객체를 수정하지 않고 새로운 객체를 반환합니다.\n * @returns {T} - 업데이트된 객체\n *\n * @example\n * // 존재하는 경로를 업데이트하는 경우\n * const obj: { a: { b: number } } = { a: { b: 1 } };\n * set(obj, 'a.b', 2);\n * // obj: { a: { b: 2 } }\n *\n * @example\n * // 존재하지 않는 경로를 업데이트하는 경우\n * const obj: { a?: { b?: number } } = {};\n * set(obj, 'a?.b', 2);\n * // { a: { b: 2 } }\n *\n * @example\n * // 불변하게 업데이트하는 경우\n * const originalObj: { a: { b: number } } = { a: { b: 1 } };\n * const updatedObj = set(originalObj, 'a.b', 2, { immutable: true });\n * // originalObj: { a: { b: 1 } }\n * // updatedObj: { a: { b: 2 } }\n */\nexport function set<\n T extends Record<string, unknown>,\n P extends PropertyPath<T>,\n V extends GetByPath<T, P>\n>(obj: T, path: P, value: V, options?: { immutable?: boolean }): T;\n\n/**\n * @description 객체의 특정 경로를 업데이트하고 새로운 객체를 반환합니다.\n *\n * 점 표기법(dot notation)을 사용하여 중첩된 객체의 깊은 속성에 접근할 수 있습니다.\n * 주어진 객체의 타입에 옵셔널 프로퍼티가 있는 경우, 옵셔널(?) 경로로 접근해야 합니다.\n *\n * immutable 옵션을 true로 설정하면, 원본 객체를 수정하지 않고 새로운 객체를 반환합니다.\n *\n * @template T - 업데이트할 객체의 타입\n * @template P - 업데이트할 경로의 타입\n * @template V - 업데이트 함수의 타입\n *\n * @param {T} obj - 업데이트할 객체\n * @param {P} path - 업데이트할 경로\n * @param {V} updater - 현재 값을 받아 새로운 값을 반환하는 함수, 해당 함수의 반환 값을 기반으로 객체의 특정 경로를 업데이트 진행\n * @param {boolean} [options.immutable=false] - true일 경우, 원본 객체를 수정하지 않고 새로운 객체를 반환합니다.\n * @returns {T} - 업데이트된 객체\n *\n * @example\n * // 존재하는 경로를 업데이트하는 경우\n * const obj: { a: { b: number } } = { a: { b: 1 } };\n * set(obj, 'a.b', (value) => value + 1);\n * // { a: { b: 2 } }\n *\n * @example\n * // 존재하지 않는 경로를 업데이트하는 경우\n * const obj: { a?: { b?: number } } = {};\n * set(obj, 'a?.b', (value) => (value ?? 0) + 1);\n * // obj: { a: { b: 1 } }\n *\n * @example\n * // 불변하게 업데이트하는 경우\n * const originalObj: { a: { b: number } } = { a: { b: 1 } };\n * const updatedObj = set(originalObj, 'a.b', (value) => value + 1, { immutable: true });\n * // originalObj: { a: { b: 1 } }\n * // updatedObj: { a: { b: 2 } }\n */\nexport function set<\n T extends Record<string, unknown>,\n P extends PropertyPath<T>,\n V extends (value: GetByPath<T, P>) => GetByPath<T, P>\n>(obj: T, path: P, updater: V, options?: { immutable?: boolean }): T;\n\nexport function set<\n T extends Record<string, unknown>,\n P extends PropertyPath<T>,\n V extends GetByPath<T, P> | ((value: GetByPath<T, P>) => GetByPath<T, P>)\n>(obj: T, path: P, value: V, options: { immutable?: boolean } = {}): T {\n const immutable = options?.immutable ?? false;\n const clonedObj = immutable ? cloneDeep(obj) : obj;\n const resolvedPath = path.replace(/\\?/g, '');\n const paths = resolvedPath.split('.');\n\n let current: Record<string, any> = clonedObj;\n\n for (let i = 0; i < paths.length - 1; i++) {\n const currentPath = paths[i];\n\n if (!hasProperty(current, currentPath) || isNil(current[currentPath])) {\n current[currentPath] = {};\n }\n\n current = current[currentPath];\n }\n\n const lastPath = paths[paths.length - 1];\n\n if (typeof value === 'function') {\n current[lastPath] = value(get(clonedObj, resolvedPath));\n } else {\n current[lastPath] = value;\n }\n\n return clonedObj;\n}\n"],"names":[],"mappings":";;;;;AA4FO,SAAS,IAId,GAAA,EAAQ,IAAA,EAAS,KAAA,EAAU,OAAA,GAAmC,EAAC,EAAM;AACrE,EAAA,MAAM,SAAA,GAAY,SAAS,SAAA,IAAa,KAAA;AACxC,EAAA,MAAM,SAAA,GAAY,SAAA,GAAY,SAAA,CAAU,GAAG,CAAA,GAAI,GAAA;AAC/C,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAC3C,EAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,KAAA,CAAM,GAAG,CAAA;AAEpC,EAAA,IAAI,OAAA,GAA+B,SAAA;AAEnC,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,MAAA,GAAS,GAAG,CAAA,EAAA,EAAK;AACzC,IAAA,MAAM,WAAA,GAAc,MAAM,CAAC,CAAA;AAE3B,IAAA,IAAI,CAAC,YAAY,OAAA,EAAS,WAAW,KAAK,KAAA,CAAM,OAAA,CAAQ,WAAW,CAAC,CAAA,EAAG;AACrE,MAAA,OAAA,CAAQ,WAAW,IAAI,EAAC;AAAA,IAC1B;AAEA,IAAA,OAAA,GAAU,QAAQ,WAAW,CAAA;AAAA,EAC/B;AAEA,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AAEvC,EAAA,IAAI,OAAO,UAAU,UAAA,EAAY;AAC/B,IAAA,OAAA,CAAQ,QAAQ,CAAA,GAAI,KAAA,CAAM,GAAA,CAAI,SAAA,EAAW,YAAY,CAAC,CAAA;AAAA,EACxD,CAAA,MAAO;AACL,IAAA,OAAA,CAAQ,QAAQ,CAAA,GAAI,KAAA;AAAA,EACtB;AAEA,EAAA,OAAO,SAAA;AACT;;;;"}