Skip to content

Commit

Permalink
Fix array concatenation bug
Browse files Browse the repository at this point in the history
  • Loading branch information
supermacro committed Feb 25, 2021
1 parent c587f6f commit a5e66a8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
17 changes: 16 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,21 @@ type ExtractErrAsyncTypes<T extends readonly ResultAsync<unknown, unknown>[]> =
[idx in keyof T]: T[idx] extends ResultAsync<unknown, infer E> ? E : never
}


const appendValueToEndOfList = <T>(value: T) => (list: T[]): T[] => {
// need to wrap `value` inside of an array in order to prevent
// Array.prototype.concat from destructuring the contents of `value`
// into `list`.
//
// Otherwise you will receive [ 'hi', 1, 2, 3 ]
// when you actually expected a tuple containing [ 'hi', [ 1, 2, 3 ] ]
if (Array.isArray(value)) {
return list.concat([ value ])
}

return list.concat(value)
}

/**
* Short circuits on the FIRST Err value that we find
*/
Expand All @@ -30,7 +45,7 @@ const combineResultList = <T, E>(resultList: Result<T, E>[]): Result<T[], E> =>
acc.isOk()
? result.isErr()
? err(result.error)
: acc.map((values) => values.concat(result.value))
: acc.map(appendValueToEndOfList(result.value))
: acc,
ok([]) as Result<T[], E>,
)
Expand Down
32 changes: 28 additions & 4 deletions tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,24 @@ describe('Utils', () => {

expect(result._unsafeUnwrap()).toEqual(['Yooooo', 123, true])
})

it('Does not destructure / concatenate arrays', () => {
type HomogenousList = [
Result<string[], boolean>,
Result<number[], string>,
]

const homogenousList: HomogenousList = [
ok(['hello', 'world']),
ok([1, 2, 3])
]

type ExpectedResult = Result<[ string[], number[] ], boolean | string>

const result: ExpectedResult = combine(homogenousList)

expect(result._unsafeUnwrap()).toEqual([ [ 'hello', 'world' ], [ 1, 2, 3 ]])
})
})

describe('Async `combine`', () => {
Expand Down Expand Up @@ -424,19 +442,25 @@ describe('Utils', () => {
})

it('Combines heterogeneous lists', async () => {
type HeterogenousList = [ ResultAsync<string, string>, ResultAsync<number, number>, ResultAsync<boolean, boolean> ]
type HeterogenousList = [
ResultAsync<string, string>,
ResultAsync<number, number>,
ResultAsync<boolean, boolean>,
ResultAsync<number[], string>,
]

const heterogenousList: HeterogenousList = [
okAsync('Yooooo'),
okAsync(123),
okAsync(true),
okAsync([ 1, 2, 3]),
]

type ExpecteResult = Result<[ string, number, boolean ], string | number | boolean>
type ExpecteResult = Result<[ string, number, boolean, number[] ], string | number | boolean>

const result: ExpecteResult= await combine(heterogenousList)
const result: ExpecteResult = await combine(heterogenousList)

expect(result._unsafeUnwrap()).toEqual(['Yooooo', 123, true])
expect(result._unsafeUnwrap()).toEqual(['Yooooo', 123, true, [ 1, 2, 3 ]])
})
})
})
Expand Down

0 comments on commit a5e66a8

Please sign in to comment.