import { List, toList } from './List'; import { ifDefined } from '../utils/If'; export type Entry = [key: string, value: T]; export function entries(subject: { [p: string]: T } | ArrayLike): List> { return ifDefined( subject, () => toList>([...Object.entries(subject), ...Object.entries(Object.getPrototypeOf(subject) ?? {})] as Entry[]), () => toList>() ); } export function values(subject: { [p: string]: T } | ArrayLike): List { return toList([...Object.values(subject), ...Object.values(Object.getPrototypeOf(subject) ?? {})]); } export function keys(subject: { [p: string]: T } | ArrayLike): List { return toList([...Object.keys(subject), ...Object.keys(Object.getPrototypeOf(subject) ?? {})]); } export function extractKeys, K extends keyof T>( obj: T, keys: K[] | readonly (keyof T)[] ): { keys: Pick; } & Omit { return keys .filter((k): k is K => k in obj) .reduce( (acc, key) => { (acc.keys as T)[key] = obj[key]; delete acc[key]; return acc; }, { keys: {} as Pick, ...obj } ); }