export function postfixObjKeys( obj: A, postfix: B ): { [Key in `${keyof A extends string ? keyof A : never}${B}`]: string } { return Object.fromEntries( Object.entries(obj).map(([k, v]) => [`${k}${postfix}`, v]) ) as any } // a bit odd but keeping backward compat for values >8 while fixing below export function sizeToSpace(v: number) { if (v === 0) return 0 if (v === 2) return 0.5 if (v === 4) return 1 if (v === 8) return 1.5 if (v <= 16) return Math.round(v * 0.333) return Math.floor(v * 0.7 - 12) } export function objectFromEntries( arr: ARR_T ): EntriesToObject { return Object.fromEntries(arr) as EntriesToObject } export type EntriesType = | [PropertyKey, unknown][] | ReadonlyArray export type DeepWritable = { -readonly [P in keyof OBJ_T]: DeepWritable } export type UnionToIntersection = // From https://stackoverflow.com/a/50375286 (UNION_T extends any ? (k: UNION_T) => void : never) extends (k: infer I) => void ? I : never export type UnionObjectFromArrayOfPairs = DeepWritable extends (infer R)[] ? R extends [infer key, infer val] ? { [prop in key & PropertyKey]: val } : never : never export type MergeIntersectingObjects = { [key in keyof ObjT]: ObjT[key] } export type EntriesToObject = MergeIntersectingObjects< UnionToIntersection> > export function objectKeys(obj: O) { return Object.keys(obj) as Array }