Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

narrow the arrays so these functions work with compiletime array literals #148

Open
github-actions bot opened this issue Mar 16, 2022 · 0 comments
Open

Comments

@github-actions
Copy link

// TODO: narrow the arrays so these functions work with compiletime array literals

    return result as never
}

/**
 * the return type of {@link findNotUndefined} and {@link findNotUndefinedAsync} when a callback is not provided
 *
 * ie. guaranteed to not be `undefined` or `null` if a result was found
 */
type FindNotUndefinedResult<T> =
    | Exclude<FindResult<NonNil<Awaited<T>>>, undefined>
    | (undefined extends Awaited<T> ? undefined : null extends Awaited<T> ? undefined : never)

// TODO: narrow the arrays so these functions work with compiletime array literals
/**
 * finds the first item in an array where the given callback doesn't return `null` or `undefined`
 * @param arr the array of `T`s to check
 * @param callback a function to run on `arr` that may return `null` or `undefined`.
 * @param runAtTheSameTime whether to execute the `callback` on each element of `arr` at the same time
 */
export const findNotUndefinedAsync: {
    <T extends unknown[]>(
        arr: T,
        runAtTheSameTime: boolean,
        callback: (it: T[number]) => Promise<unknown>,
    ): Promise<FindResult<T[number]>>
    <T extends unknown[]>(arr: T, runAtTheSameTime: boolean): Promise<
        FindNotUndefinedResult<T[number]>
    >
} = async <T extends unknown[]>(
    arr: T,
    runAtTheSameTime: boolean,
    callback: (it: T[number]) => Promise<unknown> = (value) => Promise.resolve(value),
): Promise<FindResult<T[number]>> => {
    if (runAtTheSameTime) {
        return find(arr, async (value) => !isNullOrUndefined(await callback(value))) as never
    }
    // hack so the compiler knows index is within the range of arr
    for (let index: Keys<T> = 0 as never; index < arr.length; (index as number)++) {
        const value = arr[index]
        const result = await callback(value)
        if (result) return { result, index } as never
    }
    return
}
/**
 * finds the first item in an array where the given callback doesn't return `null` or `undefined`
 * @param arr the array of `T`s to check
 * @param callback a function to run on `arr` that may return `null` or `undefined`.
 */
export const findNotUndefined: {
    <T extends unknown[]>(arr: T, callback: (it: T[number]) => unknown): FindResult<T[number]>
    <T extends unknown[]>(arr: T): FindNotUndefinedResult<T[number]>
} = <T extends unknown[]>(
    arr: T,
    callback: (it: T[number]) => unknown = (value) => value,
): FindResult<T[number]> => {
    // hack so the compiler knows index is within the range of arr
    for (let index: Keys<T> = 0 as never; index < arr.length; (index as number)++) {
        const value = arr[index]
        const result = callback(value)
        if (!isNullOrUndefined(result)) return { result, index } as never
    }
    return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant