export function validateObjectKeys(obj: any, keys: K[]): boolean { const keySet = new Set(keys) // @ts-ignore return Object.keys(obj).every(key => keySet.has(key)) } function compareStringKeys(a: string, b: string): number { return a === b ? 0 : a < b ? -1 : 1 } function compareNumberKeys(a: number, b: number): number { return a === b ? 0 : a < b ? -1 : 1 } type KeyFn = (item: T) => K export function sortByStringKey(items: T[], keyFn: KeyFn, ascending: boolean = true) { return sortByKey(compareStringKeys, items, keyFn, ascending) } export function sortByNumericKey(items: T[], keyFn: KeyFn, ascending: boolean = true) { return sortByKey(compareNumberKeys, items, keyFn, ascending) } function sortByKey(compareFn: (a: K, b: K) => number, items: T[], keyFn: (item: T) => K, ascending: boolean) { const sortedList = [...items] const order = ascending ? 1 : -1 sortedList.sort((a, b) => order * compareFn(keyFn(a), keyFn(b))) return sortedList }