Skip to content

Commit

Permalink
Improve entries functions
Browse files Browse the repository at this point in the history
  • Loading branch information
kossnocorp committed Jun 4, 2020
1 parent 6bc0e6d commit a4384ea
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 26 deletions.
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,9 @@
"sinon": "^7.3.2",
"ts-node": "^8.10.2",
"typedoc": "^0.17.0-3",
"ts-expect": "^1.1.0",
"typescript": "3.9",
"webpack": "^4.37.0"
},
"dependencies": {
"ts-expect": "^1.1.0"
}
"dependencies": {}
}
17 changes: 9 additions & 8 deletions src/entries/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export type Entry<Key, Value> = [Key, Value]

export type Entries<Key, Value> = Entry<Key, Value>[]
export interface Entries<Input extends { [key: string]: any }>
extends Array<
[keyof Input, Input extends { [key: string]: infer Value } ? Value : never]
> {}

/**
* Creates an array of arrays where the first element is the key and second is the value.
Expand All @@ -10,11 +11,11 @@ export type Entries<Key, Value> = Entry<Key, Value>[]
*
* @public
*/
export default function entries<Key extends string | number, Value>(
object: { [key in Key]: Value }
): Entries<Key, Value> {
return (Object.keys(object) as Key[]).reduce<Entries<Key, Value>>(
export default function entries<Input extends { [key: string]: any }>(
object: Input
): Entries<Input> {
return Object.keys(object).reduce<[string, any][]>(
(acc, key) => acc.concat([[key, object[key]]]),
[]
)
) as Entries<Input>
}
2 changes: 2 additions & 0 deletions src/entries/test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import assert from 'assert'
import entries from '.'
import { expectType } from 'ts-expect'

describe('entries', () => {
const object = {
Expand All @@ -10,6 +11,7 @@ describe('entries', () => {

it('returns entries array', () => {
const result = entries(object)
expectType<number | string | { d: any[] }>(result[0][1])
assert.deepEqual(result, [
['2', 3],
['a', 'B'],
Expand Down
43 changes: 28 additions & 15 deletions src/fromEntries/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Entries } from '../entries'

/**
* Returns an object composed from entries, an array of [key, value].
*
Expand All @@ -7,20 +9,31 @@
* @category Array
* @public
*/
export default function fromEntries<
Key extends string | number,
Value,
Entry extends [Key, Value],
ReturnType extends { [key: string]: Value }
>(array: Entry[]): ReturnType {
<<<<<<< HEAD
return array.reduce((acc, [key, value]) => {
acc[key] = value as ReturnType[typeof key]
=======
return array.reduce((acc, cur) => {
//@ts-ignore
acc[cur[0]] = cur[1]
>>>>>>> Add category tag
export default function fromEntries<Input>(array: Entries<Input>): Input

/**
* Returns an object composed from entries, an array of [key, value].
*
* @param array - The entries, an array of [key, value]
* @returns an object composed from the entries
*
* @category Array
* @public
*/
export default function fromEntries<Entries extends [string | number, any][]>(
array: Entries
): Entries extends [string | number, infer Value][]
? { [key: string]: Value }
: never

/**
* @internal
*/
export default function fromEntries(
array: [any, any][]
): { [key: string]: any } {
return array.reduce<{ [key: string]: any }>((acc, [key, value]) => {
acc[key] = value
return acc
}, {} as Partial<ReturnType>) as ReturnType
}, {})
}
11 changes: 11 additions & 0 deletions src/fromEntries/test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import assert from 'assert'
import fromEntries from '.'
import entries from '../entries'
import { expectType } from 'ts-expect'

describe('fromEntries', function () {
it('returns an object from array', function () {
Expand All @@ -8,9 +10,18 @@ describe('fromEntries', function () {
['b', 'c'],
[2, { d: 3 }],
])
expectType<{ [key: string]: string | number | { d: number } }>(result)
assert.deepEqual(result, { a: 1, b: 'c', '2': { d: 3 } })
})

it('allows to restore entries result', () => {
type User = { firstName: string; lastName?: string; age: number }
const user: User = { firstName: 'Sasha', age: 33 }
const result = entries(user)
const restoredUser = fromEntries(result)
expectType<User>(restoredUser)
})

it('returns an empty object if the array is empty', () => {
assert.deepEqual(fromEntries([]), {})
})
Expand Down

0 comments on commit a4384ea

Please sign in to comment.