Skip to content

Add types via JSDoc #40

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 8 additions & 13 deletions docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,21 @@ export { selectors }
// These selectors can be called in mapStateToProps() like so:
// selectors.user(state) => { name: 'test' }
// selectors.username(state) => 'test'


*
```

Returns **[Function][11]** A function that can be used to create state selectors.
Returns **SliceSelector** A function that can be used to create state selectors.

## setState

A helper function for creating simple "setter" reducers.
Given a path, it sets the state at that path to the payload of an action.

Type: [Function][11]

### Parameters

* `path` **[String][10]** Path to the part of the state that will be set
* `transform` **[Function][11]** A function with arguments `(action, state, slice)` that can be used to transform the value that will be set. `slice` is the data, if any, that already exists in the state at `path`. The default transform function simply returns the action's payload. To set the state to a constant value, simply pass the value in place of the transform function.
* `path` **[string][10]** Path to the part of the state that will be set
* `transform` **StateTransform?** A function with arguments `(action, state, slice)` that can be used to transform the value that will be set. `slice` is the data, if any, that already exists in the state at `path`. The default transform function simply returns the action's payload. To set the state to a constant value, simply pass the value in place of the transform function.

### Examples

Expand All @@ -79,20 +78,18 @@ const reducer = handleActions({
[doubleExistingCount]: setState('count', (action, state, count) => count * 2)
[resetCount]: setState('count', 0)
})

*
```

Returns **[Function][11]** A function that can be used in a reducer to handle an action.

## unsetState

A helper function for creating simple reducers that "unset" a piece of state.
Given a path, it calls lodash [unset ][12] on the state at that path.

Type: [Function][11]

### Parameters

* `path` **[String][10]** Path to the part of state to unset
* `path` **[string][10]** Path to the part of state to unset

### Examples

Expand All @@ -105,8 +102,6 @@ const clearCount = createAction('CLEAR_COUNT')
const reducer = handleActions({
[clearCount]: unsetState('count'),
})

*
```

Returns **[Function][11]** A function that can be used in a reducer to handle an action.
Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
"main": "lib/index.js",
"scripts": {
"start": "yarn install && yarn run build:development",
"build": "mkdir -p lib && babel src --out-dir lib --no-comments --minified",
"build": "mkdir -p lib && babel src --out-dir lib --no-comments --minified && yarn run types",
"build:development": "mkdir -p lib && babel src --watch --out-dir lib",
"clean": "rm -rf lib",
"docs": "documentation build src/index.js -f md -o docs.md",
"lint": "eslint src --max-warnings=0",
"prepublishOnly": "yarn run lint",
"test": "jest --coverage",
"prepare": "husky install && yarn run clean && yarn run build"
"prepare": "husky install && yarn run clean && yarn run build",
"types": "tsc"
},
"repository": "launchpadlab/lp-redux-utils",
"homepage": "https://github.com/launchpadlab/lp-redux-utils",
Expand All @@ -30,6 +31,7 @@
"LICENSE.md",
"lib/"
],
"types": "lib/types",
"devDependencies": {
"@babel/cli": "^7.22.9",
"@babel/core": "^7.22.9",
Expand All @@ -39,7 +41,8 @@
"eslint": "^8.0.0",
"husky": "^8.0.0",
"jest": "^29.0.0",
"redux": "^4.0.0"
"redux": "^4.0.0",
"typescript": "^5.1.6"
},
"dependencies": {
"lodash": "^4.17.4"
Expand Down
6 changes: 3 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export selectorForSlice from './selectorForSlice'
export setState from './setState'
export unsetState from './unsetState'
export { default as selectorForSlice } from './selectorForSlice'
export { default as setState } from './setState'
export { default as unsetState } from './unsetState'
14 changes: 10 additions & 4 deletions src/selectorForSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import { getOr } from 'lodash/fp'
* Given the path of a certain state slice, returns a function that can be used to create state selectors (helpful for `mapStateToProps()`).
*
* @param {String} slicePath - Path to slice of state.
* @returns {Function} - A function that can be used to create state selectors.
*
* @returns {SliceSelector} A function that can be used to create state selectors.
*
* @example
*
Expand Down Expand Up @@ -34,8 +33,7 @@ import { getOr } from 'lodash/fp'
* // selectors.user(state) => { name: 'test' }
* // selectors.username(state) => 'test'
*
*
**/
*/

export default function selectorForSlice (slicePath) {
return function createSelector (path, defaultValue) {
Expand All @@ -44,3 +42,11 @@ export default function selectorForSlice (slicePath) {
}
}
}

/**
* @ignore
* @callback SliceSelector

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand the difference between using a @callback tag vs a @typedef. Are both valid options for SliceSelector?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typdef doesn't work for functions 😭 .

Refer to https://github.com/LaunchPadLab/client-template/pull/436 for more details. It's a little over my head 😆 😅

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I just re-read the docs.
I thought they were using @typedef to type functions, but it was actually the function params being typed with @typedef. Functions should use @callback.

* @param {string} path - A relative path
* @param {any=} defaultValue - A default value
* @returns {(state:object) => any} The value at the slice's nested path (`slicePath.path`) or the default value provided
*/
39 changes: 27 additions & 12 deletions src/setState.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ import { set, get } from 'lodash/fp'

/**
*
* A helper function for creating simple "setter" reducers.
* A helper function for creating simple "setter" reducers.
* Given a path, it sets the state at that path to the payload of an action.
*
* @name setState
* @type Function
* @param {String} path - Path to the part of the state that will be set
* @param {Function} transform - A function with arguments `(action, state, slice)` that can be used to transform the value that will be set. `slice` is the data, if any, that already exists in the state at `path`. The default transform function simply returns the action's payload. To set the state to a constant value, simply pass the value in place of the transform function.
* @returns {Function} - A function that can be used in a reducer to handle an action.
* @type {Function}
* @param {string} path - Path to the part of the state that will be set
* @param {StateTransform} [transform=] - A function with arguments `(action, state, slice)` that can be used to transform the value that will be set. `slice` is the data, if any, that already exists in the state at `path`. The default transform function simply returns the action's payload. To set the state to a constant value, simply pass the value in place of the transform function.
* @returns {(state:any, action:Action) => any } A function that can be used in a reducer to handle an action.
*
* @example
*
* import { setState } from 'lp-redux-utils'
* import { createAction, handleActions } from 'redux-actions'
*
*
* const setCount = createAction('SET_COUNT')
* const setCountInverse = createAction('SET_COUNT_INVERSE')
* const doubleExistingCount = createAction('DOUBLE_EXISTING_COUNT')
Expand All @@ -28,12 +28,7 @@ import { set, get } from 'lodash/fp'
* [resetCount]: setState('count', 0)
* })
*
**/

function defaultTransform (action) {
return get('payload', action)
}

*/
function setState (path, transform=defaultTransform) {
return function reducer (state, action) {
const slice = get(path, state)
Expand All @@ -42,4 +37,24 @@ function setState (path, transform=defaultTransform) {
}
}

function defaultTransform (action) {
return get('payload', action)
}

/**
* @ignore
Copy link
Contributor Author

@chawes13 chawes13 Sep 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ignore stops the typedef from getting added to docs.md

* @callback StateTransform
* @param {Action} action - The action dispatched to the store
* @param {any} state - The current Redux store state
* @param {any} slice - The data, if any, that already exists in the state at `path`
* @returns {any} The value to set in the path
*/

/**
* @ignore
* @typedef Action
* @property {string} type - The action type
* @property {any=} payload - Additional data provided with the action
*/

export default setState
12 changes: 5 additions & 7 deletions src/unsetState.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
import { unset } from 'lodash/fp'

/**
*
* A helper function for creating simple reducers that "unset" a piece of state.
* Given a path, it calls lodash {@link https://lodash.com/docs/#unset|unset } on the state at that path.
*
* @name unsetState
* @type Function
* @param {String} path - Path to the part of state to unset
* @returns {Function} - A function that can be used in a reducer to handle an action.
* @type {Function}
* @param {string} path - Path to the part of state to unset
* @returns {Function} A function that can be used in a reducer to handle an action.
*
* @example
*
* import { unsetState } from 'lp-redux-utils'
* import { createAction, handleActions } from 'redux-actions'
*
*
* const clearCount = createAction('CLEAR_COUNT')
*
* const reducer = handleActions({
* [clearCount]: unsetState('count'),
* })
*
**/
*/

function unsetState (path) {
return function reducer (state) {
Expand Down
12 changes: 12 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"include": ["src"],
"exclude": ["lib", "node_modules"],
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": true,
"allowJs": true,
"outDir": "lib/types",
"declarationMap": true,
"skipLibCheck": true
}
}
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5644,6 +5644,11 @@ typed-array-length@^1.0.4:
for-each "^0.3.3"
is-typed-array "^1.1.9"

typescript@^5.1.6:
version "5.2.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78"
integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==

unbox-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
Expand Down