function isDirty( obj1: Record | null | undefined, obj2: Record | null | undefined ): boolean { const actualObj1 = obj1 ?? {} const actualObj2 = obj2 ?? {} const filteredObj1 = filterIgnored(actualObj1) const filteredObj2 = filterIgnored(actualObj2) const allKeys = new Set([...Object.keys(filteredObj1), ...Object.keys(filteredObj2)]) for (const key of allKeys) { const hasKey1 = Object.hasOwn(filteredObj1, key) const hasKey2 = Object.hasOwn(filteredObj2, key) // Различие в наличии ключа if (hasKey1 !== hasKey2) return true if (hasKey1 && hasKey2) { const val1 = filteredObj1[key] const val2 = filteredObj2[key] // Сравнение массивов if (Array.isArray(val1) && Array.isArray(val2)) { if (val1.length !== val2.length) return true const set2 = new Set(val2) if (!val1.every(item => set2.has(item))) return true } // Один массив, другой - нет else if (Array.isArray(val1) || Array.isArray(val2)) { return true } // Сравнение строк else if (typeof val1 === 'string' && typeof val2 === 'string') { if (val1.trim() !== val2.trim()) return true } // Сравнение примитивов else if (val1 !== val2) { return true } } } return false } function filterIgnored(obj: Record): Record { const filtered: Record = {} for (const key in obj) { const value = obj[key] // Обработка массивов if (Array.isArray(value)) { // Отбрасываем пустые массивы if (value.length === 0) continue // Фильтруем массивы с некорректными элементами if (value.every(item => typeof item === 'string' || typeof item === 'number' )) { filtered[key] = value } continue } // Обработка примитивов if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') { continue } // Обработка строк if (typeof value === 'string') { const trimmed = value.trim() if (trimmed === '') continue filtered[key] = trimmed } // Обработка чисел и boolean else if (value !== 0 && value !== false) { filtered[key] = value } } return filtered } function parseIntString (s: string | string[] | undefined) :number | null { if (typeof s !== 'string') return null const regex = /^[+-]?\d+$/ return regex.test(s) ? Number(s) : null } // Функция для преобразования пустых строк в null function convertEmptyStringsToNull>(obj: T): T { const result = { ...obj } as Record Object.keys(result).forEach(key => { if (result[key] === '') { result[key] = null } }) return result as T } export { isDirty, parseIntString, convertEmptyStringsToNull }