Skip to content

Commit a5e66a8

Browse files
committed
Fix array concatenation bug
1 parent c587f6f commit a5e66a8

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

src/utils.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,21 @@ type ExtractErrAsyncTypes<T extends readonly ResultAsync<unknown, unknown>[]> =
2121
[idx in keyof T]: T[idx] extends ResultAsync<unknown, infer E> ? E : never
2222
}
2323

24+
25+
const appendValueToEndOfList = <T>(value: T) => (list: T[]): T[] => {
26+
// need to wrap `value` inside of an array in order to prevent
27+
// Array.prototype.concat from destructuring the contents of `value`
28+
// into `list`.
29+
//
30+
// Otherwise you will receive [ 'hi', 1, 2, 3 ]
31+
// when you actually expected a tuple containing [ 'hi', [ 1, 2, 3 ] ]
32+
if (Array.isArray(value)) {
33+
return list.concat([ value ])
34+
}
35+
36+
return list.concat(value)
37+
}
38+
2439
/**
2540
* Short circuits on the FIRST Err value that we find
2641
*/
@@ -30,7 +45,7 @@ const combineResultList = <T, E>(resultList: Result<T, E>[]): Result<T[], E> =>
3045
acc.isOk()
3146
? result.isErr()
3247
? err(result.error)
33-
: acc.map((values) => values.concat(result.value))
48+
: acc.map(appendValueToEndOfList(result.value))
3449
: acc,
3550
ok([]) as Result<T[], E>,
3651
)

tests/index.test.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,24 @@ describe('Utils', () => {
393393

394394
expect(result._unsafeUnwrap()).toEqual(['Yooooo', 123, true])
395395
})
396+
397+
it('Does not destructure / concatenate arrays', () => {
398+
type HomogenousList = [
399+
Result<string[], boolean>,
400+
Result<number[], string>,
401+
]
402+
403+
const homogenousList: HomogenousList = [
404+
ok(['hello', 'world']),
405+
ok([1, 2, 3])
406+
]
407+
408+
type ExpectedResult = Result<[ string[], number[] ], boolean | string>
409+
410+
const result: ExpectedResult = combine(homogenousList)
411+
412+
expect(result._unsafeUnwrap()).toEqual([ [ 'hello', 'world' ], [ 1, 2, 3 ]])
413+
})
396414
})
397415

398416
describe('Async `combine`', () => {
@@ -424,19 +442,25 @@ describe('Utils', () => {
424442
})
425443

426444
it('Combines heterogeneous lists', async () => {
427-
type HeterogenousList = [ ResultAsync<string, string>, ResultAsync<number, number>, ResultAsync<boolean, boolean> ]
445+
type HeterogenousList = [
446+
ResultAsync<string, string>,
447+
ResultAsync<number, number>,
448+
ResultAsync<boolean, boolean>,
449+
ResultAsync<number[], string>,
450+
]
428451

429452
const heterogenousList: HeterogenousList = [
430453
okAsync('Yooooo'),
431454
okAsync(123),
432455
okAsync(true),
456+
okAsync([ 1, 2, 3]),
433457
]
434458

435-
type ExpecteResult = Result<[ string, number, boolean ], string | number | boolean>
459+
type ExpecteResult = Result<[ string, number, boolean, number[] ], string | number | boolean>
436460

437-
const result: ExpecteResult= await combine(heterogenousList)
461+
const result: ExpecteResult = await combine(heterogenousList)
438462

439-
expect(result._unsafeUnwrap()).toEqual(['Yooooo', 123, true])
463+
expect(result._unsafeUnwrap()).toEqual(['Yooooo', 123, true, [ 1, 2, 3 ]])
440464
})
441465
})
442466
})

0 commit comments

Comments
 (0)