Skip to content

Commit fe45bbb

Browse files
authored
fix: <Iterate> render function parameter typing not inferring correctly in conjunction with initialValue with plain values semantics (#24)
1 parent bd75364 commit fe45bbb

File tree

3 files changed

+21
-18
lines changed

3 files changed

+21
-18
lines changed

spec/tests/Iterate.spec.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ describe('`Iterate` component', () => {
138138
it(gray('When given an iterable that yields a value will render correctly'), async () => {
139139
const channel = new IterableChannelTestHelper<string>();
140140
let timesRerendered = 0;
141-
let lastRenderFnInput: undefined | IterationResult<string>;
141+
let lastRenderFnInput: undefined | IterationResult<string | undefined>;
142142

143143
const rendered = render(
144144
<Iterate value={channel}>
@@ -223,7 +223,7 @@ describe('`Iterate` component', () => {
223223
it(gray('When given an iterable that yields multiple values will render correctly'), async () => {
224224
const channel = new IterableChannelTestHelper<string>();
225225
let timesRerendered = 0;
226-
let lastRenderFnInput: undefined | IterationResult<string>;
226+
let lastRenderFnInput: undefined | IterationResult<string | undefined>;
227227

228228
const rendered = render(
229229
<Iterate value={channel}>
@@ -267,7 +267,7 @@ describe('`Iterate` component', () => {
267267
async () => {
268268
const emptyIter = (async function* () {})();
269269
let timesRerendered = 0;
270-
let lastRenderFnInput: undefined | IterationResult<string>;
270+
let lastRenderFnInput: undefined | IterationResult<string | undefined>;
271271

272272
const rendered = render(
273273
<Iterate value={emptyIter}>
@@ -333,7 +333,7 @@ describe('`Iterate` component', () => {
333333
async () => {
334334
const channel = new IterableChannelTestHelper<string>();
335335
let timesRerendered = 0;
336-
let lastRenderFnInput: undefined | IterationResult<string>;
336+
let lastRenderFnInput: undefined | IterationResult<string | undefined>;
337337

338338
const rendered = render(
339339
<Iterate value={channel}>
@@ -380,7 +380,7 @@ describe('`Iterate` component', () => {
380380
throw simulatedError;
381381
})();
382382
let timesRerendered = 0;
383-
let lastRenderFnInput: undefined | IterationResult<string>;
383+
let lastRenderFnInput: undefined | IterationResult<string | undefined>;
384384

385385
const rendered = render(
386386
<Iterate value={erroringIter}>
@@ -448,7 +448,7 @@ describe('`Iterate` component', () => {
448448
async () => {
449449
const channel = new IterableChannelTestHelper<string>();
450450
let timesRerendered = 0;
451-
let lastRenderFnInput: undefined | IterationResult<string>;
451+
let lastRenderFnInput: undefined | IterationResult<string | undefined>;
452452

453453
const simulatedErr = new Error('...');
454454

@@ -495,7 +495,7 @@ describe('`Iterate` component', () => {
495495
"When consecutively updated with new iterables will close the previous one's iterator every time and render accordingly"
496496
),
497497
async () => {
498-
let lastRenderFnInput: undefined | IterationResult<string>;
498+
let lastRenderFnInput: undefined | IterationResult<string | undefined>;
499499

500500
const [channel1, channel2] = [
501501
new IterableChannelTestHelper<string>(),
@@ -585,7 +585,7 @@ describe('`Iterate` component', () => {
585585
);
586586

587587
it(gray('When unmounted will close the last active iterator it held'), async () => {
588-
let lastRenderFnInput: undefined | IterationResult<string>;
588+
let lastRenderFnInput: undefined | IterationResult<string | undefined>;
589589

590590
const channel = new IterableChannelTestHelper<string>();
591591
const channelReturnSpy = vi.spyOn(channel, 'return');
@@ -641,7 +641,7 @@ describe('`Iterate` component', () => {
641641
yield* ['a', 'b', 'c'];
642642
})();
643643
let timesRerendered = 0;
644-
let lastRenderFnInput: undefined | IterationResult<string>;
644+
let lastRenderFnInput: undefined | IterationResult<string | undefined>;
645645

646646
const rendered = render(
647647
<Iterate value={iter}>
@@ -674,7 +674,7 @@ describe('`Iterate` component', () => {
674674
),
675675
async () => {
676676
let timesRerendered = 0;
677-
let lastRenderFnInput: undefined | IterationResult<string>;
677+
let lastRenderFnInput: undefined | IterationResult<string | undefined>;
678678
const channel = new IterableChannelTestHelper<string>();
679679

680680
const rendered = render(

src/Iterate/index.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,10 @@ function Iterate<TVal, TInitialVal = undefined>(props: IterateProps<TVal, TIniti
107107
typeof props.children === 'function'
108108
? (() => {
109109
const propsBetterTyped = props as IteratePropsWithRenderFunction<TVal, TInitialVal>;
110-
const next = useAsyncIter(propsBetterTyped.value, propsBetterTyped.initialValue);
110+
const next = useAsyncIter(
111+
propsBetterTyped.value,
112+
propsBetterTyped.initialValue as TInitialVal
113+
);
111114
return propsBetterTyped.children(next);
112115
})()
113116
: (() => {

src/useAsyncIter/index.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ export { useAsyncIter, type IterationResult };
9999
* ```
100100
*/
101101
const useAsyncIter: {
102-
<TVal>(input: TVal, initialVal?: undefined): IterationResult<TVal, undefined>;
103-
<TVal, TInitVal = undefined>(input: TVal, initialVal?: TInitVal): IterationResult<TVal, TInitVal>;
102+
<TVal>(input: TVal, initialVal?: undefined): IterationResult<TVal>;
103+
<TVal, TInitVal>(input: TVal, initialVal: TInitVal): IterationResult<TVal, TInitVal>;
104104
} = <
105105
TVal extends
106106
| undefined
@@ -120,7 +120,7 @@ const useAsyncIter: {
120120
const rerender = useSimpleRerender();
121121

122122
const stateRef = useRef<IterationResult<TVal, TInitVal>>({
123-
value: initialVal,
123+
value: initialVal as any,
124124
pendingFirst: true,
125125
done: false,
126126
error: undefined,
@@ -225,12 +225,12 @@ const useAsyncIter: {
225225
type IterationResult<TVal, TInitVal = undefined> = {
226226
/**
227227
* The most recent value received from the async iterable iteration, starting as {@link TInitVal}.
228-
* If the source was instead a plain value, it will simply be it.
228+
* If the source was a plain value instead, it will simply be it, ignoring any {@link TInitVal}.
229229
*
230-
* Starting to iterate a new async iterable at any future point on itself doesn't reset this;
231-
* only some newly resolved next value will.
230+
* When the source iterable changes and an iteration restarts with a new iterable, the same last
231+
* `value` is carried over and reflected until the new iterable resolves its first value.
232232
* */
233-
value: ExtractAsyncIterValue<TVal> | TInitVal;
233+
value: TVal extends AsyncIterable<infer J> ? J | TInitVal : TVal;
234234

235235
/**
236236
* Indicates whether the iterated async iterable is still pending its own first value to be

0 commit comments

Comments
 (0)