import { isFunction } from 'lodash' ; type FilterFunc < P extends keyof T , T > = ( item : T [ P ] ) => boolean ; returns export function propFilter < P extends string > ( prop ) { param { array } list param { function | array | string } filters return { array } return function filterByName < T extends { [ key in P ] : T [ P ] ; } > ( list , filters = [ ] ) : T [ ] { if ( isFunction ( filters ) ) { return list . filter ( ( item ) => ( filters as FilterFunc < P , T > ) ( item [ prop ] ) ) ; } if ( ! Array . isArray ( filters ) ) { filters = filters . split ( ',' ) ; } if ( filters . length === 0 ) { return list ; } if ( filters . includes ( '*' ) ) { return list ; } const options = filters . reduce ( ( acc , filter ) => { let type = 'include' ; let value = filter ; if ( filter . charAt ( 0 ) === '!' ) { type = 'exclude' ; value = filter . substr ( 1 ) ; } if ( ! acc [ type ] ) { acc [ type ] = [ ] ; } acc [ type ] . push ( value ) ; return acc ; } , { } as { [ type ] : string [ ] ; } ) ; return list . filter ( ( item ) => { const value = item [ prop ] ; const excluded = options . exclude && options . exclude . includes ( value ) ; if ( excluded ) { return false ; } const included = ! options . include || options . include . includes ( value ) ; if ( included ) { return true ; } return false ; } ) ; } ; }