type Resolver < T > = ( item : T ) => any ; type Indexer < T > = number | keyof T | symbol ; type ValueResolver < T > = Indexer < T > | Resolver < T > ; interface Array < T > { uniqueBy ( valueResolver ? ) : T [ ] ; } if ( typeof Array . prototype . uniqueBy !== 'function' ) Object . defineProperty ( Array . prototype , 'uniqueBy' , { writable : true , configurable : true , value : function < T > ( this , valueResolver ? ) { if ( ! ( valueResolver != null ) ) return [ ... new Set ( this ) ] ; const key = typeof valueResolver !== 'function' && valueResolver , map = new Map < any , T > ( ) ; valueResolver = key ? ( item ) => item ?. [ key ] ?? item : valueResolver ; for ( const item of this ) { const key = ( valueResolver as Resolver < T > ) ( item ) ; if ( ! map . has ( key ) ) map . set ( key , item ) ; } return [ ... map . values ( ) ] ; } } ) ;