diff --git a/src/common/useAsyncItersImperatively/index.ts b/src/common/useAsyncItersImperatively/index.ts index 8ae0792..0720a53 100644 --- a/src/common/useAsyncItersImperatively/index.ts +++ b/src/common/useAsyncItersImperatively/index.ts @@ -1,7 +1,6 @@ import { useEffect } from 'react'; import { type IterationResult } from '../../useAsyncIter/index.js'; import { type AsyncIterableSubject } from '../../AsyncIterableSubject/index.js'; -import { type IterationResultSet } from '../../useAsyncIterMulti/index.js'; import { type Writable } from '../Writable.js'; import { useRefWithInitialValue } from '../hooks/useRefWithInitialValue.js'; import { isAsyncIter } from '../isAsyncIter.js'; @@ -12,20 +11,61 @@ import { iterateAsyncIterWithCallbacks } from '../iterateAsyncIterWithCallbacks. export { useAsyncItersImperatively, type IterationResultSet }; -// TODO: Move the `IterationResultSet` type's home to sit together with this function here instead next to `useAsyncIterMulti` as currently - -function useAsyncItersImperatively< +const useAsyncItersImperatively: { + ( + inputs: TInputs, + onYieldCb: (vals: IterationResultSet) => void, + opts?: { + initialValues?: undefined; + defaultInitialValue?: undefined; + } + ): IterationResultSet; + + < + const TInputs extends readonly unknown[], + const TInitVals extends readonly unknown[] = readonly [], + >( + inputs: TInputs, + onYieldCb: (vals: IterationResultSet) => void, + opts: { + initialValues: TInitVals; + defaultInitialValue?: undefined; + } + ): IterationResultSet; + + ( + inputs: TInputs, + onYieldCb: (vals: IterationResultSet) => void, + opts: { + initialValues?: undefined; + defaultInitialValue: TDefaultInitValue; + } + ): IterationResultSet; + + < + const TInputs extends readonly unknown[], + const TInitVals extends readonly unknown[] = readonly [], + const TDefaultInitValue = undefined, + >( + inputs: TInputs, + onYieldCb: (vals: IterationResultSet) => void, + opts: { + initialValues: TInitVals; + defaultInitialValue: TDefaultInitValue; + } + ): IterationResultSet; +} = < const TInputs extends readonly unknown[], const TInitVals extends readonly unknown[] = readonly [], const TDefaultInitValue = undefined, >( inputs: TInputs, - onYieldCb: (vals: IterationResultSet) => void, + onYieldCb: (vals: IterationResultSet) => void, opts?: { initialValues?: TInitVals; defaultInitialValue?: TDefaultInitValue; } -): IterationResultSet { +): IterationResultSet => { const optsNormed = { initialValues: opts?.initialValues ?? [], defaultInitialValue: opts?.defaultInitialValue, @@ -33,7 +73,7 @@ function useAsyncItersImperatively< const ref = useRefWithInitialValue(() => ({ currDiffCompId: 0, - currResults: [] as IterationResultSet, + currResults: [] as IterationResultSet, activeItersMap: new Map< AsyncIterable, { @@ -130,7 +170,7 @@ function useAsyncItersImperatively< activeItersMap.set(baseIter, iterState); return iterState.currState; - }) as Writable>; + }) as Writable>; // TODO: If the consumers of `useAsyncItersImperatively` within the library are intending to use it in conjunction with `React.useEffect` (e.g. `useAsyncIterEffect`) - do we really need to do such individual length comparisons and cleanups like the following? `React.useEffect` enforces strict static-length deps anyways const numOfPrevRunItersDisappeared = numOfPrevRunIters - numOfPrevRunItersPreserved; @@ -149,4 +189,15 @@ function useAsyncItersImperatively< } return ref.current.currResults; -} +}; + +type IterationResultSet< + TValues extends readonly unknown[], + TInitValues extends readonly unknown[] = readonly [], + TDefaultInitValue = undefined, +> = { + [I in keyof TValues]: IterationResult< + TValues[I], + I extends keyof TInitValues ? TInitValues[I] : TDefaultInitValue + >; +}; diff --git a/src/useAsyncIterMulti/index.ts b/src/useAsyncIterMulti/index.ts index dc66d1a..52779b4 100644 --- a/src/useAsyncIterMulti/index.ts +++ b/src/useAsyncIterMulti/index.ts @@ -1,7 +1,9 @@ import { useSimpleRerender } from '../common/hooks/useSimpleRerender.js'; import { type IterationResult } from '../useAsyncIter/index.js'; -import { type MaybeFunction } from '../common/MaybeFunction.js'; -import { useAsyncItersImperatively } from '../common/useAsyncItersImperatively/index.js'; +import { + useAsyncItersImperatively, + type IterationResultSet, +} from '../common/useAsyncItersImperatively/index.js'; export { useAsyncIterMulti, type IterationResult, type IterationResultSet }; @@ -201,34 +203,13 @@ function useAsyncIterMulti< initialValues?: TInitValues; defaultInitialValue?: TDefaultInitValue; } -): IterationResultSet, TDefaultInitValue> { +): IterationResultSet { const update = useSimpleRerender(); const currValues = useAsyncItersImperatively(inputs, () => update(), { - initialValues: opts?.initialValues ?? [], - defaultInitialValue: opts?.defaultInitialValue, + initialValues: (opts?.initialValues ?? []) as TInitValues, + defaultInitialValue: opts?.defaultInitialValue as TDefaultInitValue, }); - const currValuesTypePatched = currValues as IterationResultSet< - TValues, - MaybeFunctions, - TDefaultInitValue - >; - - return currValuesTypePatched; + return currValues; } - -type IterationResultSet< - TValues extends readonly unknown[], - TInitValues extends readonly unknown[] = readonly [], - TDefaultInitValue = undefined, -> = { - [I in keyof TValues]: IterationResult< - TValues[I], - I extends keyof TInitValues ? TInitValues[I] : TDefaultInitValue - >; -}; - -type MaybeFunctions = { - [I in keyof T]: T[I] extends MaybeFunction ? J : T[I]; -};