Skip to content

Commit a685bce

Browse files
phryneasmarkerikson
authored andcommitted
Create slice changes (#197)
1 parent 16e0686 commit a685bce

File tree

4 files changed

+56
-63
lines changed

4 files changed

+56
-63
lines changed

docs/api/createSlice.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ hide_title: true
77

88
# `createSlice`
99

10-
A function that accepts an initial state, an object full of reducer functions, and optionally a "slice name",
10+
A function that accepts an initial state, an object full of reducer functions, and a "slice name",
1111
and automatically generates action creators and action types that correspond to the reducers and state.
1212

1313
## Parameters
@@ -20,8 +20,8 @@ function createSlice({
2020
reducers: Object<string, ReducerFunction>
2121
// The initial state for the reducer
2222
initialState: any,
23-
// An optional name, used in action types
24-
slice?: string,
23+
// A name, used in action types
24+
name: string,
2525
// An additional object of "case reducers". Keys should be other action types.
2626
extraReducers?: Object<string, ReducerFunction>
2727
})
@@ -44,9 +44,9 @@ state they are given.
4444

4545
The initial state value for this slice of state.
4646

47-
### `slice`
47+
### `name`
4848

49-
An optional string name for this slice of state. Generated action type constants will use this as a prefix.
49+
A string name for this slice of state. Generated action type constants will use this as a prefix.
5050

5151
### `extraReducers`
5252

@@ -73,7 +73,7 @@ to force the TS compiler to accept the computed property.)
7373

7474
```ts
7575
{
76-
slice : string,
76+
name : string,
7777
reducer : ReducerFunction,
7878
actions : Object<string, ActionCreator},
7979
}
@@ -104,7 +104,7 @@ import { createSlice } from 'redux-starter-kit'
104104
import { createStore, combineReducers } from 'redux'
105105
106106
const counter = createSlice({
107-
slice: 'counter', // slice is optional, and could be blank ''
107+
name: 'counter',
108108
initialState: 0,
109109
reducers: {
110110
increment: state => state + 1,
@@ -114,7 +114,7 @@ const counter = createSlice({
114114
})
115115
116116
const user = createSlice({
117-
slice: 'user',
117+
name: 'user',
118118
initialState: { name: '', age: 20 },
119119
reducers: {
120120
setUserName: (state, action) => {

src/createSlice.test.ts

+32-42
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,35 @@ import { createSlice } from './createSlice'
22
import { createAction, PayloadAction } from './createAction'
33

44
describe('createSlice', () => {
5-
describe('when slice is empty', () => {
6-
const { actions, reducer } = createSlice({
7-
reducers: {
8-
increment: state => state + 1,
9-
multiply: (state, action: PayloadAction<number>) =>
10-
state * action.payload
11-
},
12-
initialState: 0
13-
})
14-
15-
it('should create increment action', () => {
16-
expect(actions.hasOwnProperty('increment')).toBe(true)
17-
})
18-
19-
it('should create multiply action', () => {
20-
expect(actions.hasOwnProperty('multiply')).toBe(true)
21-
})
22-
23-
it('should have the correct action for increment', () => {
24-
expect(actions.increment()).toEqual({
25-
type: 'increment',
26-
payload: undefined
27-
})
28-
})
29-
30-
it('should have the correct action for multiply', () => {
31-
expect(actions.multiply(3)).toEqual({
32-
type: 'multiply',
33-
payload: 3
34-
})
5+
describe('when slice is undefined', () => {
6+
it('should throw an error', () => {
7+
expect(() =>
8+
// @ts-ignore
9+
createSlice({
10+
reducers: {
11+
increment: state => state + 1,
12+
multiply: (state, action: PayloadAction<number>) =>
13+
state * action.payload
14+
},
15+
initialState: 0
16+
})
17+
).toThrowError()
3518
})
19+
})
3620

37-
describe('when using reducer', () => {
38-
it('should return the correct value from reducer with increment', () => {
39-
expect(reducer(undefined, actions.increment())).toEqual(1)
40-
})
41-
42-
it('should return the correct value from reducer with multiply', () => {
43-
expect(reducer(2, actions.multiply(3))).toEqual(6)
44-
})
21+
describe('when slice is an empty string', () => {
22+
it('should throw an error', () => {
23+
expect(() =>
24+
createSlice({
25+
name: '',
26+
reducers: {
27+
increment: state => state + 1,
28+
multiply: (state, action: PayloadAction<number>) =>
29+
state * action.payload
30+
},
31+
initialState: 0
32+
})
33+
).toThrowError()
4534
})
4635
})
4736

@@ -51,7 +40,7 @@ describe('createSlice', () => {
5140
increment: state => state + 1
5241
},
5342
initialState: 0,
54-
slice: 'cool'
43+
name: 'cool'
5544
})
5645

5746
it('should create increment action', () => {
@@ -80,7 +69,7 @@ describe('createSlice', () => {
8069
}
8170
},
8271
initialState,
83-
slice: 'user'
72+
name: 'user'
8473
})
8574

8675
it('should set the username', () => {
@@ -94,6 +83,7 @@ describe('createSlice', () => {
9483
const addMore = createAction('ADD_MORE')
9584

9685
const { reducer } = createSlice({
86+
name: 'test',
9787
reducers: {
9888
increment: state => state + 1,
9989
multiply: (state, action) => state * action.payload
@@ -116,7 +106,7 @@ describe('createSlice', () => {
116106
const prepare = jest.fn((payload, somethingElse) => ({ payload }))
117107

118108
const testSlice = createSlice({
119-
slice: 'test',
109+
name: 'test',
120110
initialState: 0,
121111
reducers: {
122112
testReducer: {
@@ -137,7 +127,7 @@ describe('createSlice', () => {
137127
const reducer = jest.fn()
138128

139129
const testSlice = createSlice({
140-
slice: 'test',
130+
name: 'test',
141131
initialState: 0,
142132
reducers: {
143133
testReducer: {

src/createSlice.ts

+11-8
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export interface Slice<
2323
/**
2424
* The slice name.
2525
*/
26-
slice: string
26+
name: string
2727

2828
/**
2929
* The slice's reducer.
@@ -47,7 +47,7 @@ export interface CreateSliceOptions<
4747
/**
4848
* The slice's name. Used to namespace the generated action types.
4949
*/
50-
slice?: string
50+
name: string
5151

5252
/**
5353
* The initial state to be returned by the slice reducer.
@@ -140,12 +140,12 @@ type RestrictEnhancedReducersToMatchReducerAndPrepare<
140140
> = { reducers: SliceCaseReducersCheck<S, NoInfer<CR>> }
141141

142142
function getType(slice: string, actionKey: string): string {
143-
return slice ? `${slice}/${actionKey}` : actionKey
143+
return `${slice}/${actionKey}`
144144
}
145145

146146
/**
147147
* A function that accepts an initial state, an object full of reducer
148-
* functions, and optionally a "slice name", and automatically generates
148+
* functions, and a "slice name", and automatically generates
149149
* action creators and action types that correspond to the
150150
* reducers and state.
151151
*
@@ -166,14 +166,17 @@ export function createSlice<
166166
>(
167167
options: CreateSliceOptions<State, CaseReducers>
168168
): Slice<State, CaseReducerActions<CaseReducers>> {
169-
const { slice = '', initialState } = options
169+
const { name, initialState } = options
170+
if (!name) {
171+
throw new Error('`name` is a required option for createSlice')
172+
}
170173
const reducers = options.reducers || {}
171174
const extraReducers = options.extraReducers || {}
172175
const actionKeys = Object.keys(reducers)
173176

174177
const reducerMap = actionKeys.reduce((map, actionKey) => {
175178
let maybeEnhancedReducer = reducers[actionKey]
176-
map[getType(slice, actionKey)] =
179+
map[getType(name, actionKey)] =
177180
typeof maybeEnhancedReducer === 'function'
178181
? maybeEnhancedReducer
179182
: maybeEnhancedReducer.reducer
@@ -185,7 +188,7 @@ export function createSlice<
185188
const actionMap = actionKeys.reduce(
186189
(map, action) => {
187190
let maybeEnhancedReducer = reducers[action]
188-
const type = getType(slice, action)
191+
const type = getType(name, action)
189192
map[action] =
190193
typeof maybeEnhancedReducer === 'function'
191194
? createAction(type)
@@ -196,7 +199,7 @@ export function createSlice<
196199
)
197200

198201
return {
199-
slice,
202+
name,
200203
reducer,
201204
actions: actionMap
202205
}

type-tests/files/createSlice.typetest.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function expectType<T>(t: T) {
1212
const firstAction = createAction<{ count: number }>('FIRST_ACTION')
1313

1414
const slice = createSlice({
15-
slice: 'counter',
15+
name: 'counter',
1616
initialState: 0,
1717
reducers: {
1818
increment: (state: number, action) => state + action.payload,
@@ -47,7 +47,7 @@ function expectType<T>(t: T) {
4747
*/
4848
{
4949
const counter = createSlice({
50-
slice: 'counter',
50+
name: 'counter',
5151
initialState: 0,
5252
reducers: {
5353
increment: state => state + 1,
@@ -85,7 +85,7 @@ function expectType<T>(t: T) {
8585
*/
8686
{
8787
const counter = createSlice({
88-
slice: 'counter',
88+
name: 'counter',
8989
initialState: 0,
9090
reducers: {
9191
increment: state => state + 1,
@@ -112,7 +112,7 @@ function expectType<T>(t: T) {
112112
*/
113113
{
114114
const counter = createSlice({
115-
slice: 'test',
115+
name: 'test',
116116
initialState: { counter: 0, concat: '' },
117117
reducers: {
118118
incrementByStrLen: {
@@ -153,7 +153,7 @@ function expectType<T>(t: T) {
153153
{
154154
// typings:expect-error
155155
const counter = createSlice({
156-
slice: 'counter',
156+
name: 'counter',
157157
initialState: { counter: 0 },
158158
reducers: {
159159
increment: {

0 commit comments

Comments
 (0)