Personal helpers and convenience functions for TypeScript
Links:
npm install @carlwr/typescript-extra
# run checks and tests:
npm qa
function allUnique<T>(xs: T[]): boolean
whether the elements of xs
are unique, in the ===
sense
O(n) (if the hash tables behave, and they should for primitives) (constants likely not too great)
function assertNever(_: never): never
function drain<T>(xs: [T, ...T[]]): () => T
Stateful iterator yielding the elements of xs
.
When the last element is reached, calls will continue to return that element indefinitely.
example:
const next = drain([1, 2, 3])
next() // => 1
next() // => 2
next() // => 3
next() // => 3
next() // => 3 (returns 3 forever)
function extract<T>(root: unknown, pred: (k: string, v: unknown) => undefined | T): T[]
walk root
recursively while collecting all T
s for which pred
returnes a defined result
example:
const root = {
A: 1,
b: 0,
c: {
99: [{A:2}, {e:"zero"}, null],
A: 3
}
}
function pred(k: string, v: any): number|undefined {
if (k === 'A' && typeof v === 'number') { return v }
return undefined
}
const result = extract<number>(root, pred)
// result === [1, 2, 3]
function flatmapNonEmpty<T, U>(xs: readonly [T, T], fn: (x: T) => [U, ...U[]]): [U, ...U[]]
Flatmap over a non-empty array with a function returning a non-empty arrays. Return the flattened result as a non-empty array.
function getMatch(re: RegExp, str: string): string
return the match of the regex, or throw if no match
function hasAtleastTwo<T>(xs: readonly T[]): xs is [T, T, ...T[]]
function hasKey<T, K>(value: T, key: K): value is T & { [P in PropertyKey]: unknown }
whether the value is an object that has the key
in the true
branch, the type of the passed argument is narrowed to include the knowledge that the key is present, without destroying any other knowledge about the type prior to the call
function isDefined<T>(x: undefined | null | T): x is NonNullable<T>
function isEmpty<T>(xs: readonly T[]): xs is []
function isNonEmpty<T>(xs: readonly T[]): xs is [T, ...T[]]
function isSingle<T>(xs: readonly T[]): xs is [T]
function mapAsync<T, U>(xs: readonly T[], f: (x: T) => Promise<U>): Promise<U[]>
function mapFilterAsync<T, U>(xs: readonly T[], f: (x: T) => Promise<undefined | null | U>): Promise<U[]>
function mapNonEmpty<T, U>(xs: readonly [T, T], fn: (x: T) => U): [U, ...U[]]
Map over a non-empty array while preserving the type as non-empty
function memoized<T>(f: () => Promise<T>): () => Promise<T>
Cached, lazy, single-flight evaluation of a promise.
A rejected promise is cached as well, i.e. no re-attempts (failures are assumed to be permanent).
function partitionAsync<A, B>(items: readonly A[], pred: (a: A) => Promise<B>): Promise<readonly [A[], A[]]>
function rm_rf(path: string): Promise<void>
remove a file or directory recursively; ignore errors
function safeIndex<T>(xs: readonly [T, T], i: number): T
return the i
th element of xs
, or throw if i
is out of bounds
function trim(str: string): string
the .trim()
method as a function
trim(str) <=> str.trim()
function withoutFirstSubstring(first: string, str: string): string
remove a substring from the beginning of a string; throw if str
does not start with first
example:
withoutFirstSubstring('e', 'ego') // => 'go'