Skip to content

Commit

Permalink
Merge pull request #8 from zero-one-group/feat/implement-assoc
Browse files Browse the repository at this point in the history
Add Dict.assoc
  • Loading branch information
mobily committed Dec 14, 2021
2 parents 3624071 + dd26337 commit 2daeb36
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 0 deletions.
73 changes: 73 additions & 0 deletions __tests__/Dict/set.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { expectType } from 'ts-expect'

import { D, pipe } from '../..'

const obj = {
0: true,
x: 1,
y: 'abc',
}

describe('set', () => {
it('provides correct types', () => {
expectType<typeof obj & { z: boolean }>(D.set(obj, 'z', true))
expectType<typeof obj>(D.set(obj, 'y', 'def'))
expectType<Omit<typeof obj, 'y'> & { y: number }>(D.set(obj, 'y', 123))

expectType<typeof obj & { 1: string }>(D.set(obj, 1, 'abc'))
expectType<typeof obj>(D.set(obj, 0, false))
expectType<Omit<typeof obj, 0> & { 0: string }>(D.set(obj, 0, 'abc'))
})

it('adds a new property or updates an existing one.', () => {
expect(D.set(obj, 'z', true)).toEqual({ ...obj, z: true })
expect(D.set(obj, 'x', 2)).toEqual({ ...obj, x: 2 })

expect(D.set(obj, 1, 2)).toEqual({ ...obj, 1: 2 })
expect(D.set(obj, 0, 'abc')).toEqual({ ...obj, 0: 'abc' })
})

it('*', () => {
expect(
D.set({ name: 'Joe', location: 'Warsaw' }, 'location', 'Gdańsk'),
).toEqual({ name: 'Joe', location: 'Gdańsk' })

expect(D.set({ 0: false, 1: true }, 1, 'abc')).toEqual({
0: false,
1: 'abc',
})
})
})

describe('set (pipe)', () => {
it('provides correct types', () => {
expectType<typeof obj & { z: boolean }>(pipe(obj, D.set('z', true)))
expectType<typeof obj>(pipe(obj, D.set('y', 'def')))
expectType<Omit<typeof obj, 'y'> & { y: number }>(
pipe(obj, D.set('y', 123)),
)

expectType<typeof obj & { 1: string }>(pipe(obj, D.set(1, 'abc')))
expectType<typeof obj>(pipe(obj, D.set(0, false)))
expectType<Omit<typeof obj, 0> & { 0: string }>(pipe(obj, D.set(0, 'abc')))
})

it('adds a new property or updates an existing one.', () => {
expect(pipe(obj, D.set('z', true))).toEqual({ ...obj, z: true })
expect(pipe(obj, D.set('x', 2))).toEqual({ ...obj, x: 2 })

expect(pipe(obj, D.set(1, 2))).toEqual({ ...obj, 1: 2 })
expect(pipe(obj, D.set(0, 'abc'))).toEqual({ ...obj, 0: 'abc' })
})

it('*', () => {
expect(
pipe({ name: 'Joe', location: 'Warsaw' }, D.set('location', 'Gdańsk')),
).toEqual({ name: 'Joe', location: 'Gdańsk' })

expect(pipe({ 0: false, 1: true }, D.set(1, 'abc'))).toEqual({
0: false,
1: 'abc',
})
})
})
23 changes: 23 additions & 0 deletions docs/api/generated/_dict.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,29 @@ pipe(
) // → { age: 20 }
```

### set

Adds a property. Equivalent to merging with `{key: value}`
```ts
function set<T, K extends string | number, V>(dict: T, key: K, value: V): T & Record<K, V>
function set<T, K extends string | number, V>(key: K, value: V): (dict: T) => T & Record<K, V>
```

```ts
D.set({ name: 'Joe', location: 'Warsaw' }, 'location', 'Gdańsk') // → { name: 'Joe', location: 'Gdańsk' }
D.set({ 0: false, 1: true }, 1, 'abc') // → {
0: false,
1: 'abc',
}
pipe({ name: 'Joe', location: 'Warsaw' }, D.set('location', 'Gdańsk')) // → { name: 'Joe', location: 'Gdańsk' }
pipe({ 0: false, 1: true }, D.set(1, 'abc')) // → {
0: false,
1: 'abc',
}
```

### toPairs

Converts an object into an array of `[key, value]` tuples.
Expand Down
7 changes: 7 additions & 0 deletions src/Dict/Dict.res
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ export fromPairs = dict => Js.Dict.fromArray(dict)
%comment("Merges two provided objects.")
export merge = (fst, snd) => assign2(makeEmpty(), fst, snd)

%comment("Adds a property. Equivalent to merging with `{key: value}`")
export set = (dict, key, value) => {
let obj = merge(makeEmpty(), dict)
Js.Dict.set(obj, key, value)
obj
}

%comment("Transforms each value in the object to a new value using the provided function.")
export map = (dict, mapFn) => {
dict
Expand Down
5 changes: 5 additions & 0 deletions src/Dict/Dict.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ export declare const keys: <T extends Record<string, unknown>>(
dict: T,
) => ReadonlyArray<keyof T>
export declare const merge: <A, B>(fst: A, snd: B) => A & B
export declare const set: <T, K extends string | number, V>(
dict: T,
key: K,
value: V,
) => T & Record<K, V>
export declare const map: <T extends Record<string, any>, R>(
dict: T,
mapFn: (value: T[keyof T]) => R,
Expand Down
13 changes: 13 additions & 0 deletions src/Dict/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@ export declare function merge<A, B>(fst: A, snd: B): A & B

export declare function merge<A, B>(snd: B): (fst: A) => A & B

/** Adds a property. Equivalent to merging with `{key: value}` */

export declare function set<T, K extends string | number, V>(
dict: T,
key: K,
value: V,
): T & Record<K, V>

export declare function set<T, K extends string | number, V>(
key: K,
value: V,
): (dict: T) => T & Record<K, V>

/** Transforms each value in the object to a new value using the provided function. */

export declare function map<T extends Record<string, any>, R>(
Expand Down

0 comments on commit 2daeb36

Please sign in to comment.