Skip to content

Commit 35a3cc1

Browse files
authored
prevent any-casting of S generic on entityAdapter reducer-like f… (#436)
* prevent any-casting of S generic on entityAdapter reducer-like functions * remove `map` from entityAdapter * remove references to `map` from the docs * update API report * remove export
1 parent 980dcbe commit 35a3cc1

10 files changed

+166
-146
lines changed

docs/api/createEntityAdapter.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,6 @@ export interface Dictionary<T> extends DictionaryNum<T> {
118118

119119
export type Update<T> = { id: EntityId; changes: Partial<T> }
120120

121-
export type EntityMap<T> = (entity: T) => T
122-
123121
export interface EntityState<T> {
124122
ids: EntityId[]
125123
entities: Dictionary<T>
@@ -171,9 +169,6 @@ export interface EntityStateAdapter<T> {
171169
state: S,
172170
entities: PayloadAction<T[]>
173171
): S
174-
175-
map<S extends EntityState<T>>(state: S, map: EntityMap<T>): S
176-
map<S extends EntityState<T>>(state: S, map: PayloadAction<EntityMap<T>>): S
177172
}
178173

179174
export interface EntitySelectors<T, V> {
@@ -208,7 +203,6 @@ The primary content of an entity adapter is a set of generated reducer functions
208203
- `updateMany`: accepts an array of update objects, and updates all corresponding entities
209204
- `upsertOne`: accepts a single entity. If an entity with that ID exists, the fields in the update will be merged into the existing entity, with any matching fields overwriting the existing values. If the entity does not exist, it will be added.
210205
- `upsertMany`: accepts an array of entities that will be upserted.
211-
- `map`: accepts a callback function that will be run against each existing entity, and may return a change description object. Afterwards, all changes will be merged into the corresponding existing entities.
212206

213207
Each method has a signature that looks like:
214208

etc/redux-toolkit.api.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,6 @@ export interface EntityAdapter<T> extends EntityStateAdapter<T> {
185185
sortComparer: false | Comparer<T>;
186186
}
187187

188-
// @alpha (undocumented)
189-
export type EntityMap<T> = (entity: T) => T;
190-
191188
// @alpha (undocumented)
192189
export interface EntityState<T> {
193190
// (undocumented)

src/entities/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ export {
44
EntityState,
55
EntityAdapter,
66
Update,
7-
EntityMap,
87
IdSelector,
98
Comparer
109
} from './models'

src/entities/models.ts

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { PayloadAction } from '../createAction'
2+
import { IsAny } from '../tsHelpers'
23

34
/**
45
* @alpha
@@ -34,11 +35,6 @@ export interface Dictionary<T> extends DictionaryNum<T> {
3435
*/
3536
export type Update<T> = { id: EntityId; changes: Partial<T> }
3637

37-
/**
38-
* @alpha
39-
*/
40-
export type EntityMap<T> = (entity: T) => T
41-
4238
/**
4339
* @alpha
4440
*/
@@ -52,50 +48,76 @@ export interface EntityDefinition<T> {
5248
sortComparer: false | Comparer<T>
5349
}
5450

51+
export type PreventAny<S, T> = IsAny<S, EntityState<T>, S>
52+
5553
export interface EntityStateAdapter<T> {
56-
addOne<S extends EntityState<T>>(state: S, entity: T): S
57-
addOne<S extends EntityState<T>>(state: S, action: PayloadAction<T>): S
54+
addOne<S extends EntityState<T>>(state: PreventAny<S, T>, entity: T): S
55+
addOne<S extends EntityState<T>>(
56+
state: PreventAny<S, T>,
57+
action: PayloadAction<T>
58+
): S
5859

59-
addMany<S extends EntityState<T>>(state: S, entities: T[]): S
60-
addMany<S extends EntityState<T>>(state: S, entities: PayloadAction<T[]>): S
60+
addMany<S extends EntityState<T>>(state: PreventAny<S, T>, entities: T[]): S
61+
addMany<S extends EntityState<T>>(
62+
state: PreventAny<S, T>,
63+
entities: PayloadAction<T[]>
64+
): S
6165

62-
setAll<S extends EntityState<T>>(state: S, entities: T[]): S
63-
setAll<S extends EntityState<T>>(state: S, entities: PayloadAction<T[]>): S
66+
setAll<S extends EntityState<T>>(state: PreventAny<S, T>, entities: T[]): S
67+
setAll<S extends EntityState<T>>(
68+
state: PreventAny<S, T>,
69+
entities: PayloadAction<T[]>
70+
): S
6471

65-
removeOne<S extends EntityState<T>>(state: S, key: EntityId): S
66-
removeOne<S extends EntityState<T>>(state: S, key: PayloadAction<EntityId>): S
72+
removeOne<S extends EntityState<T>>(state: PreventAny<S, T>, key: EntityId): S
73+
removeOne<S extends EntityState<T>>(
74+
state: PreventAny<S, T>,
75+
key: PayloadAction<EntityId>
76+
): S
6777

68-
removeMany<S extends EntityState<T>>(state: S, keys: EntityId[]): S
6978
removeMany<S extends EntityState<T>>(
70-
state: S,
79+
state: PreventAny<S, T>,
80+
keys: EntityId[]
81+
): S
82+
removeMany<S extends EntityState<T>>(
83+
state: PreventAny<S, T>,
7184
keys: PayloadAction<EntityId[]>
7285
): S
7386

74-
removeAll<S extends EntityState<T>>(state: S): S
87+
removeAll<S extends EntityState<T>>(state: PreventAny<S, T>): S
7588

76-
updateOne<S extends EntityState<T>>(state: S, update: Update<T>): S
7789
updateOne<S extends EntityState<T>>(
78-
state: S,
90+
state: PreventAny<S, T>,
91+
update: Update<T>
92+
): S
93+
updateOne<S extends EntityState<T>>(
94+
state: PreventAny<S, T>,
7995
update: PayloadAction<Update<T>>
8096
): S
8197

82-
updateMany<S extends EntityState<T>>(state: S, updates: Update<T>[]): S
8398
updateMany<S extends EntityState<T>>(
84-
state: S,
99+
state: PreventAny<S, T>,
100+
updates: Update<T>[]
101+
): S
102+
updateMany<S extends EntityState<T>>(
103+
state: PreventAny<S, T>,
85104
updates: PayloadAction<Update<T>[]>
86105
): S
87106

88-
upsertOne<S extends EntityState<T>>(state: S, entity: T): S
89-
upsertOne<S extends EntityState<T>>(state: S, entity: PayloadAction<T>): S
107+
upsertOne<S extends EntityState<T>>(state: PreventAny<S, T>, entity: T): S
108+
upsertOne<S extends EntityState<T>>(
109+
state: PreventAny<S, T>,
110+
entity: PayloadAction<T>
111+
): S
90112

91-
upsertMany<S extends EntityState<T>>(state: S, entities: T[]): S
92113
upsertMany<S extends EntityState<T>>(
93-
state: S,
114+
state: PreventAny<S, T>,
115+
entities: T[]
116+
): S
117+
upsertMany<S extends EntityState<T>>(
118+
state: PreventAny<S, T>,
94119
entities: PayloadAction<T[]>
95120
): S
96-
97-
map<S extends EntityState<T>>(state: S, map: EntityMap<T>): S
98-
map<S extends EntityState<T>>(state: S, map: PayloadAction<EntityMap<T>>): S
99121
}
100122

101123
export interface EntitySelectors<T, V> {

src/entities/sorted_state_adapter.test.ts

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -331,40 +331,6 @@ describe('Sorted State Adapter', () => {
331331
})
332332
})
333333

334-
it('should let you map over entities in the state', () => {
335-
const firstChange = { ...TheGreatGatsby, title: 'First change' }
336-
const secondChange = { ...AClockworkOrange, title: 'Second change' }
337-
338-
const withMany = adapter.setAll(state, [
339-
TheGreatGatsby,
340-
AClockworkOrange,
341-
AnimalFarm
342-
])
343-
344-
const withUpdates = adapter.map(withMany, book =>
345-
book.title === TheGreatGatsby.title
346-
? firstChange
347-
: book.title === AClockworkOrange.title
348-
? secondChange
349-
: book
350-
)
351-
352-
expect(withUpdates).toEqual({
353-
ids: [AnimalFarm.id, TheGreatGatsby.id, AClockworkOrange.id],
354-
entities: {
355-
[AnimalFarm.id]: AnimalFarm,
356-
[TheGreatGatsby.id]: {
357-
...TheGreatGatsby,
358-
...firstChange
359-
},
360-
[AClockworkOrange.id]: {
361-
...AClockworkOrange,
362-
...secondChange
363-
}
364-
}
365-
})
366-
})
367-
368334
it('should let you add one entity to the state with upsert()', () => {
369335
const withOneEntity = adapter.upsertOne(state, TheGreatGatsby)
370336
expect(withOneEntity).toEqual({

src/entities/sorted_state_adapter.ts

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ import {
33
IdSelector,
44
Comparer,
55
EntityStateAdapter,
6-
Update,
7-
EntityMap,
8-
EntityId
6+
Update
97
} from './models'
108
import { createStateOperator } from './state_adapter'
119
import { createUnsortedStateAdapter } from './unsorted_state_adapter'
@@ -72,21 +70,6 @@ export function createSortedStateAdapter<T>(
7270
}
7371
}
7472

75-
function mapMutably(updatesOrMap: EntityMap<T>, state: R): void {
76-
const updates: Update<T>[] = state.ids.reduce(
77-
(changes: Update<T>[], id: EntityId) => {
78-
const change = updatesOrMap(state.entities[id]!)
79-
if (change !== state.entities[id]) {
80-
changes.push({ id, changes: change })
81-
}
82-
return changes
83-
},
84-
[]
85-
)
86-
87-
updateManyMutably(updates, state)
88-
}
89-
9073
function upsertOneMutably(entity: T, state: R): void {
9174
return upsertManyMutably([entity], state)
9275
}
@@ -151,7 +134,6 @@ export function createSortedStateAdapter<T>(
151134
setAll: createStateOperator(setAllMutably),
152135
addMany: createStateOperator(addManyMutably),
153136
updateMany: createStateOperator(updateManyMutably),
154-
upsertMany: createStateOperator(upsertManyMutably),
155-
map: createStateOperator(mapMutably)
137+
upsertMany: createStateOperator(upsertManyMutably)
156138
}
157139
}

src/entities/unsorted_state_adapter.test.ts

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -250,40 +250,6 @@ describe('Unsorted State Adapter', () => {
250250
expect(entities.c).toBeTruthy()
251251
})
252252

253-
it('should let you map over entities in the state', () => {
254-
const firstChange = { ...TheGreatGatsby, title: 'First change' }
255-
const secondChange = { ...AClockworkOrange, title: 'Second change' }
256-
257-
const withMany = adapter.setAll(state, [
258-
TheGreatGatsby,
259-
AClockworkOrange,
260-
AnimalFarm
261-
])
262-
263-
const withUpdates = adapter.map(withMany, book =>
264-
book.title === TheGreatGatsby.title
265-
? firstChange
266-
: book.title === AClockworkOrange.title
267-
? secondChange
268-
: book
269-
)
270-
271-
expect(withUpdates).toEqual({
272-
ids: [TheGreatGatsby.id, AClockworkOrange.id, AnimalFarm.id],
273-
entities: {
274-
[TheGreatGatsby.id]: {
275-
...TheGreatGatsby,
276-
...firstChange
277-
},
278-
[AClockworkOrange.id]: {
279-
...AClockworkOrange,
280-
...secondChange
281-
},
282-
[AnimalFarm.id]: AnimalFarm
283-
}
284-
})
285-
})
286-
287253
it('should let you add one entity to the state with upsert()', () => {
288254
const withOneEntity = adapter.upsertOne(state, TheGreatGatsby)
289255
expect(withOneEntity).toEqual({

src/entities/unsorted_state_adapter.ts

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
EntityStateAdapter,
44
IdSelector,
55
Update,
6-
EntityMap,
76
EntityId
87
} from './models'
98
import { createStateOperator } from './state_adapter'
@@ -57,7 +56,7 @@ export function createUnsortedStateAdapter<T>(
5756
}
5857
}
5958

60-
function removeAll<S extends R>(state: S): S {
59+
function removeAll(state: R): any {
6160
return Object.assign({}, state, {
6261
ids: [],
6362
entities: {}
@@ -120,22 +119,6 @@ export function createUnsortedStateAdapter<T>(
120119
}
121120
}
122121

123-
function mapMutably(map: EntityMap<T>, state: R): void {
124-
const changes: Update<T>[] = state.ids.reduce(
125-
(changes: Update<T>[], id: EntityId) => {
126-
const change = map(state.entities[id]!)
127-
if (change !== state.entities[id]) {
128-
changes.push({ id, changes: change })
129-
}
130-
return changes
131-
},
132-
[]
133-
)
134-
const updates = changes.filter(({ id }) => id in state.entities)
135-
136-
return updateManyMutably(updates, state)
137-
}
138-
139122
function upsertOneMutably(entity: T, state: R): void {
140123
return upsertManyMutably([entity], state)
141124
}
@@ -167,7 +150,6 @@ export function createUnsortedStateAdapter<T>(
167150
upsertOne: createStateOperator(upsertOneMutably),
168151
upsertMany: createStateOperator(upsertManyMutably),
169152
removeOne: createStateOperator(removeOneMutably),
170-
removeMany: createStateOperator(removeManyMutably),
171-
map: createStateOperator(mapMutably)
153+
removeMany: createStateOperator(removeManyMutably)
172154
}
173155
}

src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ export {
7575
EntityState,
7676
EntityAdapter,
7777
Update,
78-
EntityMap,
7978
IdSelector,
8079
Comparer
8180
} from './entities/models'

0 commit comments

Comments
 (0)