const tuple = < T extends Array < unknown > > ( ... args ) : T => args ; const keys = < O extends object > ( obj ) => Object . keys ( obj ) as Array < keyof O > ; const entries = < K extends string , V > ( obj ) => keys ( obj ) . map ( key => tuple ( key , obj [ key ] ) ) ; const fromEntries = < K extends string , V > ( arr ) => Object . assign ( { } , ... arr . map ( ( [ k , v ] ) => ( { [ k ] : v } ) ) ) as Record < K , V > ; export const pickBy = < K extends string , V , Result extends V > ( obj , predicate ) => fromEntries ( entries ( obj ) . filter ( ( entry ) : entry is [ K , Result ] => { const [ key , value ] = entry ; return predicate ( key , value ) ; } ) ) ;