Skip to content

Commit

Permalink
feat(utils): [at] allow nilable targets
Browse files Browse the repository at this point in the history
Signed-off-by: Lexus Drumgold <unicornware@flexdevelopment.llc>
  • Loading branch information
unicornware committed Jul 31, 2023
1 parent 538739e commit ea14c9d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 10 deletions.
26 changes: 20 additions & 6 deletions src/utils/__tests__/at.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,31 @@
import testSubject from '../at'

describe('unit:utils/at', () => {
it('should return indexed value or fallback', () => {
it('should return fallback if index is not in range', () => {
// Arrange
const cases: Parameters<typeof testSubject>[] = [
['', 0, ''],
[[], 1, null],
[null, faker.number.int(), undefined],
[undefined, faker.number.int(), null]
]

// Act + Expect
cases.forEach(([target, index, fallback]) => {
expect(testSubject(target, index, fallback)).to.equal(fallback)
})
})

it('should return indexed value if index is in range', () => {
// Arrange
const cases: [...Parameters<typeof testSubject>, unknown][] = [
['', 0, '', ''],
['abcdef', '1', undefined, 'b'],
[['a', 'b', 'c', 'd', 'e', 'f'], -1, undefined, 'f']
['abcdef', '1', null, 'b'],
[['a', 'b', 'c', 'd', 'e', 'f'], -5, null, 'b']
]

// Act + Expect
cases.forEach(([value, index, fallback, expected]) => {
expect(testSubject(value, index, fallback)).to.equal(expected)
cases.forEach(([target, index, fallback, expected]) => {
expect(testSubject(target, index, fallback)).to.equal(expected)
})
})
})
8 changes: 4 additions & 4 deletions src/utils/at.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module tutils/utils/at
*/

import type { At, NumberLike, Optional } from '#src/types'
import type { At, Nilable, NumberLike, Optional } from '#src/types'
import cast from './cast'
import isUndefined from './is-undefined'

Expand All @@ -26,7 +26,7 @@ import isUndefined from './is-undefined'
* @return {At<T, K, F>} Indexed value or `fallback`
*/
const at = <
T extends string | readonly unknown[],
T extends Nilable<string | readonly unknown[]>,
K extends NumberLike,
F = undefined
>(
Expand All @@ -37,9 +37,9 @@ const at = <
/**
* Item or character in {@linkcode target} at {@linkcode index}.
*
* @const {Optional<T[number]>} ret
* @const {Optional<NonNullable<T>[number]>} ret
*/
const ret: Optional<T[number]> = target.at(+index.toString())
const ret: Optional<NonNullable<T>[number]> = (target ?? []).at(+index)

return cast(isUndefined(ret) ? fallback : ret)
}
Expand Down

0 comments on commit ea14c9d

Please sign in to comment.