Skip to content

Commit

Permalink
feat(operators/chunk): improve types
Browse files Browse the repository at this point in the history
When the `chunkSize` value is known at compile-time, the return type of the operator will now reflect that and return a suitable union of tuples instead of an array with a generic length.

For example, `chunk(3)` will now return `Operator<T, [T] | [T, T] | [T, T, T]>` instead of `Operator<T, Array<T>>`.

Closes #13
  • Loading branch information
lazarljubenovic committed Nov 3, 2023
1 parent 41a7a2e commit 0a19949
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/operators/chunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,24 @@ import { Operator } from '../core/types'
* )
* // => [[1, 2], [3, 4], [5]]
*/
export function chunk<T> (chunkSize: 1): Operator<T, [T]>
export function chunk<T> (chunkSize: 2): Operator<T, [T] | [T, T]>
export function chunk<T> (chunkSize: 3): Operator<T, [T] | [T, T] | [T, T, T]>
export function chunk<T> (chunkSize: 4): Operator<T, [T] | [T, T] | [T, T, T] | [T, T, T, T]>
export function chunk<T> (chunkSize: 5): Operator<T, [T] | [T, T] | [T, T, T] | [T, T, T, T] | [T, T, T, T, T]>
export function chunk<T> (chunkSize: 6): Operator<T, [T] | [T, T] | [T, T, T] | [T, T, T, T] | [T, T, T, T, T] | [T, T, T, T, T, T]>
export function chunk<T> (chunkSize: 7): Operator<T, [T] | [T, T] | [T, T, T] | [T, T, T, T] | [T, T, T, T, T] | [T, T, T, T, T, T] | [T, T, T, T, T, T, T]>
export function chunk<T> (chunkSize: 8): Operator<T, [T] | [T, T] | [T, T, T] | [T, T, T, T] | [T, T, T, T, T] | [T, T, T, T, T, T] | [T, T, T, T, T, T, T] | [T, T, T, T, T, T, T, T]>
export function chunk<T> (chunkSize: 9): Operator<T, [T] | [T, T] | [T, T, T] | [T, T, T, T] | [T, T, T, T, T] | [T, T, T, T, T, T] | [T, T, T, T, T, T, T] | [T, T, T, T, T, T, T, T] | [T, T, T, T, T, T, T, T, T]>
export function chunk<T> (chunkSize: 10): Operator<T, [T] | [T, T] | [T, T, T] | [T, T, T, T] | [T, T, T, T, T] | [T, T, T, T, T, T] | [T, T, T, T, T, T, T] | [T, T, T, T, T, T, T, T] | [T, T, T, T, T, T, T, T, T] | [T, T, T, T, T, T, T, T, T, T]>
export function chunk<T> (chunkSize: number): Operator<T, Array<T>>
export function chunk<T> (chunkSize: number): Operator<T, Array<T>> {

if (!Number.isInteger(chunkSize) || chunkSize < 1) {
throw new RangeError(`Chunk size must be an integer not less than 1; an attempt was made to define the chunk size as ${chunkSize}.`)
}

return function *(iterable: Iterable<T>): IterableIterator<Array<T>> {
return function* (iterable: Iterable<T>): IterableIterator<Array<T>> {
const buffer: Array<T> = []
let count: number = 0
for (const item of iterable) {
Expand Down
10 changes: 10 additions & 0 deletions tests/operators.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ describe(`Operators`, () => {
chai.assert.throws(() => j.chunk(-1), RangeError)
})

it(`infers the correct type for chunk size 1`, () => {
const result = j.pipe([1, 2, 3], j.chunk(1))
type Test = AssertTrue<IsExact<typeof result, IterableIterator<[number]>>>
})

it(`infers the correct type for chunk size 2`, () => {
const result = j.pipe([1, 2, 3], j.chunk(2))
type Test = AssertTrue<IsExact<typeof result, IterableIterator<[number] | [number, number]>>>
})

it(`@example 1`, () => {
const actual = j.pipe(
[1, 2, 3, 4],
Expand Down

0 comments on commit 0a19949

Please sign in to comment.