From cfd555723b7461116f2cd3d891a10d0e1b61a4ad Mon Sep 17 00:00:00 2001 From: garrettmills Date: Thu, 20 Jan 2022 00:55:11 -0600 Subject: [PATCH] Add whereDefined and mapCall methods to Collection class --- src/util/collection/Collection.ts | 31 ++++++++++++++++++++++++++----- src/util/support/types.ts | 4 ++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/util/collection/Collection.ts b/src/util/collection/Collection.ts index bcd1138..0224bd1 100644 --- a/src/util/collection/Collection.ts +++ b/src/util/collection/Collection.ts @@ -14,7 +14,7 @@ type MaybeCollectionIndex = CollectionIndex | undefined type ComparisonFunction = (item: CollectionItem, otherItem: CollectionItem) => number import { WhereOperator, applyWhere, whereMatch } from './where' -import {Awaitable, Either, isLeft, right, unright} from '../support/types' +import {Awaitable, Either, isLeft, Maybe, MethodsOf, right, unright} from '../support/types' const collect = (items: CollectionItem[]): Collection => Collection.collect(items) const toString = (item: unknown): string => String(item) @@ -293,7 +293,7 @@ class Collection { * Stops executing if a single truth case is found. * @param func */ - some(func: (item: T) => boolean): boolean { + some(func: (item: T) => Maybe): boolean { return this.storedItems.some(func) } @@ -355,6 +355,23 @@ class Collection { return right(new Collection(newItems)) } + /** + * Map a method on the underlying type, passing it any required parameters. + * This is delightfully type-safe. + * @param method + * @param params + */ + mapCall>(method: T2, ...params: Parameters): Collection> { + return this.map(x => x[method](...params)) + } + + /** + * Map each element in the collection to a string. + */ + strings(): Collection { + return this.map(x => String(x)) + } + /** * Create a new collection by mapping the items in this collection using the given function, * excluding any for which the function returns undefined. @@ -441,8 +458,12 @@ class Collection { * Return a new collection filtered by the given function. * @param func */ - filter(func: KeyFunction): Collection { - return new Collection(this.storedItems.filter(func)) + filter(func?: KeyFunction): Collection { + return new Collection(this.storedItems.filter(func ?? Boolean)) + } + + whereDefined(): Collection> { + return this.filter() as unknown as Collection> } /** @@ -780,7 +801,7 @@ class Collection { * Return the max value of the given key. * @param key */ - max(key: KeyOperator): number { + max(key: KeyOperator): number { const values = this.allAsNumbers(key) return Math.max(...values) } diff --git a/src/util/support/types.ts b/src/util/support/types.ts index fe70768..7033ed9 100644 --- a/src/util/support/types.ts +++ b/src/util/support/types.ts @@ -68,3 +68,7 @@ export interface TypeTag { export type PrefixTypeArray = [T, ...TArr] export type SuffixTypeArray = [...TArr, T] export type TypeArraySignature = (...params: TArr) => TReturn + +export type MethodsOf any> = { + [K in keyof T]: T[K] extends TMethod ? K : never +}[keyof T]