Skip to content

Commit d91316f

Browse files
authored
Merge pull request #99 from dgreene1/disallowSeedWithOptionalNested
Disallow seed with optional nested
2 parents 8df1905 + 187eef7 commit d91316f

File tree

7 files changed

+1234
-300
lines changed

7 files changed

+1234
-300
lines changed

README.md

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,28 @@
44

55
`mergePartially` is a convenience method for overwriting only the values you want
66

7-
## I see lots of TypeScript stuff. Can I use this in JavaScript too?
7+
<!-- toc -->
88

9-
Yes. Even though the examples are in TypeScript (since it helps to illustrate the problem that `mergePartially` solves), you can just remove the type annotations when using `mergePartially`.
9+
- [Design Goals](#design-goals)
10+
- [Why would you want to use this:](#why-would-you-want-to-use-this)
11+
* [First, let's try to write the flexible factory function without mergePartially](#first-lets-try-to-write-the-flexible-factory-function-without-mergepartially)
12+
* [Now let's refactor using mergePartially](#now-lets-refactor-using-mergepartially)
13+
- [Examples](#examples)
14+
- [F.A.Q. / Troubleshooting](#faq--troubleshooting)
15+
* [Why wouldn't I just use Object.assign or the spread operator?](#why-wouldnt-i-just-use-objectassign-or-the-spread-operator)
16+
* [I see lots of TypeScript stuff. Can I use this in JavaScript too?](#i-see-lots-of-typescript-stuff-can-i-use-this-in-javascript-too)
17+
* [What's the difference between .deep and .shallow?](#whats-the-difference-between-deep-and-shallow)
18+
* [Why is `.shallow` even necessary?](#why-is-shallow-even-necessary)
19+
* [Why is my return type some strange error string?](#why-is-my-return-type-some-strange-error-string)
20+
- [Contributions](#contributions)
21+
22+
<!-- tocstop -->
23+
24+
## Design Goals
25+
26+
1. the resulting object will always be the same type/`interface` as the seed object
27+
2. it will always be “Typescript first” so you know the type definitions will not differ at runtime (like many of this library's competitors)
28+
3. all PRs should allow consumers of the library to feel confident to use this library in production and bullet-proof testing scenarios. High code-coverage percentages gaurantee this.
1029

1130
## Why would you want to use this:
1231

@@ -70,7 +89,7 @@ Wow look how much fewer lines and characters we have to write to accomplish the
7089
import { mergePartially, NestedPartial } from 'merge-partially';
7190

7291
function makeFakeUser(overrides?: NestedPartial<IUser>): IUser {
73-
return mergePartially(
92+
return mergePartially.deep(
7493
{
7594
id: 1,
7695
age: 42,
@@ -85,3 +104,63 @@ function makeFakeUser(overrides?: NestedPartial<IUser>): IUser {
85104
## Examples
86105

87106
See [the unit tests](https://github.com/dgreene1/merge-partially/blob/master/src/index.spec.ts) for various examples.
107+
108+
## F.A.Q. / Troubleshooting
109+
110+
### Why wouldn't I just use Object.assign or the spread operator?
111+
112+
These two functions have different goals. `Object.assign` can merge two different types into a combination type. `mergePartially` always returns the same type as the seed object. That's one of many reasons why `mergePartially` is safer than `Object.assign`.
113+
114+
### I see lots of TypeScript stuff. Can I use this in JavaScript too?
115+
116+
Yes. Even though the examples are in TypeScript (since it helps to illustrate the problem that `mergePartially` solves), you can just remove the type annotations when using `mergePartially`.
117+
118+
### What's the difference between .deep and .shallow?
119+
120+
- The main difference is that `.deep` allows you to pass multiple levels of partially supplied objects but `.shallow` only allows partial objects at the first level.
121+
- On a more technical level, `.deep` allows you to pass in `NestedPartial<T>` as where `.shallow` only accepts `Partial<T>`
122+
- Both will always return the full object
123+
124+
For example:
125+
126+
```ts
127+
interface ISeed {
128+
a: {
129+
b: {
130+
c: string;
131+
d: string;
132+
};
133+
};
134+
}
135+
136+
const seed: ISeed = {
137+
a: {
138+
b: {
139+
c: 'c',
140+
d: 'd',
141+
},
142+
},
143+
};
144+
145+
const deepResult = mergePartially.deep(seed, { a: { b: { d: 'new d' } } });
146+
const shallowResult = mergePartially.shallow(seed, {
147+
a: {
148+
b: {
149+
c: 'I had to supply a value for c here but I did not have to supply it in .deep',
150+
d: 'new d',
151+
},
152+
},
153+
});
154+
```
155+
156+
### Why is `.shallow` even necessary?
157+
158+
There are some data types that are "less-compatible" with the library and therefore require a workaround ([click here for the description](https://github.com/dgreene1/merge-partially/blob/master/whyShallowInstead.md)). It should be rare that you need to use `.shallow`, but you might prefer `.shallow` over `.deep` anyway for explicitness.
159+
160+
### Why is my return type some strange error string?
161+
162+
In order to meet the design goals (see above), mergePartially proactively prevents certain data combinations. See this link for more information on the soluton: [https://github.com/dgreene1/merge-partially/blob/master/whyShallowInstead.md](https://github.com/dgreene1/merge-partially/blob/master/whyShallowInstead.md)
163+
164+
## Contributions
165+
166+
PRs are welcome. To contribute, please either make a Github issue or find one you'd like to work on, then fork the repo to make the change.

0 commit comments

Comments
 (0)