| import type { ValueOf } from "$lib/types.js"; |
|
|
| |
| export function keys<T extends object>(o: T) { |
| return Object.keys(o) as Array<`${keyof T & (string | number | boolean | null | undefined)}`>; |
| } |
|
|
| |
| export function entries<T extends object>(o: T): [keyof T, T[keyof T]][] { |
| return Object.entries(o) as [keyof T, T[keyof T]][]; |
| } |
|
|
| |
| export function fromEntries<T extends object>(entries: [keyof T, T[keyof T]][]): T { |
| return Object.fromEntries(entries) as T; |
| } |
|
|
| export function omit<T extends Record<string, unknown>, K extends keyof T>(obj: T, ...keys: K[]): Omit<T, K> { |
| const result = {} as Omit<T, K>; |
| for (const key of Object.keys(obj)) { |
| if (!keys.includes(key as unknown as K)) { |
| result[key as keyof Omit<T, K>] = obj[key] as ValueOf<Omit<T, K>>; |
| } |
| } |
| return result; |
| } |
|
|
| export function pick<T extends Record<string, unknown>, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> { |
| const result = {} as Pick<T, K>; |
| for (const key of keys) { |
| result[key] = obj[key] as ValueOf<Pick<T, K>>; |
| } |
| return result; |
| } |
|
|
| |
| export function snapshot<T>(s: T): T { |
| return $state.snapshot(s) as T; |
| } |
|
|
| |
| |
| |
| |
| |
| export function tryGet<T extends Record<string, unknown>>(obj: T, key: string): T[keyof T] | undefined { |
| return obj[key as keyof T]; |
| } |
|
|
| |
| type DeepMergeable = { [key: string]: any }; |
|
|
| function isPlainObject(value: unknown): value is Record<string, unknown> { |
| return value !== null && typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype; |
| } |
|
|
| export function deepMerge<T extends DeepMergeable, U extends DeepMergeable>(target: T, source: U): T & U { |
| const result: DeepMergeable = { ...target }; |
|
|
| for (const key in source) { |
| if (Object.prototype.hasOwnProperty.call(source, key)) { |
| const sourceValue = source[key]; |
| const targetValue = result[key]; |
|
|
| |
| if (Array.isArray(sourceValue)) { |
| result[key] = Array.isArray(targetValue) ? [...targetValue, ...sourceValue] : [...sourceValue]; |
| continue; |
| } |
|
|
| |
| if (isPlainObject(sourceValue)) { |
| result[key] = |
| Object.prototype.hasOwnProperty.call(result, key) && isPlainObject(result[key]) |
| ? deepMerge(result[key], sourceValue) |
| : deepMerge({}, sourceValue); |
| continue; |
| } |
|
|
| |
| result[key] = sourceValue; |
| } |
| } |
|
|
| return result as T & U; |
| } |
|
|
| export function renameKey<T extends object>( |
| obj: T, |
| oldKey: keyof T, |
| newKey: string, |
| ): { [K in keyof T as K extends typeof oldKey ? typeof newKey : K]: T[K] } { |
| const entries = Object.entries(obj); |
| |
| const result: any = {}; |
| for (const [key, value] of entries) { |
| if (key === oldKey) { |
| result[newKey] = value; |
| } else { |
| result[key] = value; |
| } |
| } |
| return result; |
| } |
|
|
| export function unmutableSet<T extends object>(obj: T, key: keyof T, value: T[keyof T]) { |
| const newObj = { ...obj }; |
| newObj[key] = value; |
| return newObj; |
| } |
|
|
| export function deleteKey<T extends object>(obj: T, key: keyof T) { |
| const newObj = { ...obj }; |
| delete newObj[key]; |
| return newObj; |
| } |
|
|