type KeyOf < T extends object > = object extends T ? keyof any : keyof T ;
type ValueOf < T extends object > = object extends T ? unknown : T [ keyof T ];
export type KeyFilterFunction < T extends object = object > = (
* Functions can use this type to accept either an array of keys or a
T extends object = object ,
Key extends keyof any = keyof any ,
> = KeyFilterFunction < T > | readonly Key [];
* Extract the keys of an object that pass a filter.
export type FilteredKeys <
F extends KeyFilter < T > | null | undefined ,
> = Extract < keyof T , F extends readonly any [] ? F [ number ] : any >;
import { isArray } from " @/helpers/is-array.ts " ;
* Pick a list of properties from an object into a new object.
* ⚠️ When used with a predicate function, `pick` is potentially
* unsafe, because of partial type matching performed by TypeScript.
* If you pass an object with more properties than its TypeScript type
* has listed, the `value` and `key` parameter types of your callback
* const a = { a: 1, b: 2, c: 3 }
* pick(a, ['a', 'c']) // => { a: 1, c: 3 }
* pick(a, (value, key) => value > 1) // => { b: 2, c: 3 }
export function pick < T extends object , F extends KeyFilter < T , keyof T >> (
) : Pick < T , FilteredKeys < T , F >>;
export function pick < T extends object > (
filter : KeyFilter < T , keyof T > | null ,
let keys : ( keyof T )[] = filter as any ;
keys = Reflect . ownKeys ( obj ) as ( keyof T )[];
return keys . reduce ( ( acc , key ) => {
Object . hasOwnProperty . call ( obj , key ) &&
( filter == null || filter (( obj as any )[ key ] , key , obj ));