Commit 2501a772 authored by Robert Knight's avatar Robert Knight

Enable typechecking for sidebar/store/modules

- Add JSDoc for the `actionTypes` function. This uses an advanced
  TS feature called "mapped types" [1] to specify that the result is an
  object with the same keys as the input object, but where the values
  are strings rather than functions.

  Going forwards there are likely better ways to replace `actionTypes`.
  The original purpose was to make sure that the `type` field of each action
  object matches up with a key of the `updates` object.

- Fix various existing JSDoc errors
- Add imports for the existing `Group` and `Annotation` references
- Add missing `group` property to `Annotation` type

[1] https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types
    (See in particular the `in keyof T` mentions).
parent d5b8d349
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
* sidebar. * sidebar.
*/ */
/**
* @typedef {import('../../../types/api').Annotation} Annotation
*/
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import * as metadata from '../../util/annotation-metadata'; import * as metadata from '../../util/annotation-metadata';
...@@ -56,7 +60,7 @@ function findByTag(annotations, tag) { ...@@ -56,7 +60,7 @@ function findByTag(annotations, tag) {
* from the service. * from the service.
* *
* @param {Object} annotation * @param {Object} annotation
* @param {Number} tag - The `$tag` value that should be used for this * @param {string} tag - The `$tag` value that should be used for this
* if it doesn't have a `$tag` already * if it doesn't have a `$tag` already
* @return {Object} - annotation with local (`$*`) fields set * @return {Object} - annotation with local (`$*`) fields set
*/ */
...@@ -226,7 +230,7 @@ function updateFlagStatus(id, isFlagged) { ...@@ -226,7 +230,7 @@ function updateFlagStatus(id, isFlagged) {
/** /**
* Add these `annotations` to the current collection of annotations in the store. * Add these `annotations` to the current collection of annotations in the store.
* *
* @param {Object}[] annotations - Array of annotation objects to add. * @param {Annotation[]} annotations - Array of annotation objects to add.
*/ */
function addAnnotations(annotations) { function addAnnotations(annotations) {
return function (dispatch, getState) { return function (dispatch, getState) {
...@@ -344,7 +348,7 @@ function unhideAnnotation(id) { ...@@ -344,7 +348,7 @@ function unhideAnnotation(id) {
/** /**
* Return all loaded annotations which have been saved to the server. * Return all loaded annotations which have been saved to the server.
* *
* @param {state} - The global app state * @param {Object} state - The global app state
*/ */
function savedAnnotations(state) { function savedAnnotations(state) {
return state.annotations.annotations.filter(function (ann) { return state.annotations.annotations.filter(function (ann) {
...@@ -365,7 +369,7 @@ function annotationExists(state, id) { ...@@ -365,7 +369,7 @@ function annotationExists(state, id) {
* If an annotation does not have an ID because it has not been created on * If an annotation does not have an ID because it has not been created on
* the server, there will be no entry for it in the returned array. * the server, there will be no entry for it in the returned array.
* *
* @param {string[]} Local tags of annotations to look up * @param {string[]} tags - Local tags of annotations to look up
*/ */
function findIDsForTags(state, tags) { function findIDsForTags(state, tags) {
const ids = []; const ids = [];
......
...@@ -4,6 +4,10 @@ import * as util from '../util'; ...@@ -4,6 +4,10 @@ import * as util from '../util';
import session from './session'; import session from './session';
/**
* @typedef {import('../../../types/api').Group} Group
*/
function init() { function init() {
return { return {
/** /**
...@@ -97,7 +101,7 @@ function loadGroups(groups) { ...@@ -97,7 +101,7 @@ function loadGroups(groups) {
/** /**
* Return the currently focused group. * Return the currently focused group.
* *
* @return {Group|null} * @return {Group|undefined|null}
*/ */
function focusedGroup(state) { function focusedGroup(state) {
if (!state.groups.focusedGroupId) { if (!state.groups.focusedGroupId) {
......
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
* WebSocket connection to h's real-time API. * WebSocket connection to h's real-time API.
*/ */
/**
* @typedef {import('../../../types/api').Annotation} Annotation
*/
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { actionTypes } from '../util'; import { actionTypes } from '../util';
......
...@@ -313,7 +313,7 @@ function setForceVisible(id, visible) { ...@@ -313,7 +313,7 @@ function setForceVisible(id, visible) {
/** /**
* Sets which annotations are currently focused. * Sets which annotations are currently focused.
* *
* @param {Array<string>} Tags of annotations to focus * @param {string[]} tags - Tags of annotations to focus
*/ */
function focusAnnotations(tags) { function focusAnnotations(tags) {
return { return {
......
...@@ -41,7 +41,7 @@ function setShowHighlights(show) { ...@@ -41,7 +41,7 @@ function setShowHighlights(show) {
} }
/** /**
* @param {boolean} sidebarState - If the sidebar is open * @param {boolean} opened - If the sidebar is open
*/ */
function setSidebarOpened(opened) { function setSidebarOpened(opened) {
return { type: actions.SET_SIDEBAR_OPENED, opened }; return { type: actions.SET_SIDEBAR_OPENED, opened };
......
/** /**
* Return an object where each key in `updateFns` is mapped to the key itself. * Return an object where each key in `updateFns` is mapped to the key itself.
*
* @template {Object.<string,Function>} T
* @param {T} reducers - Object containing reducer functions
* @return {{ [index in keyof T]: string }}
*/ */
export function actionTypes(updateFns) { export function actionTypes(reducers) {
return Object.keys(updateFns).reduce(function (types, key) { return Object.keys(reducers).reduce(function (types, key) {
types[key] = key; types[key] = key;
return types; return types;
}, {}); }, /** @type {any} */ ({}));
} }
/** /**
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
"shared/*.js", "shared/*.js",
"shared/components/*.js", "shared/components/*.js",
"sidebar/*.js", "sidebar/*.js",
"sidebar/store/modules/*.js",
"sidebar/services/*.js", "sidebar/services/*.js",
"sidebar/util/*.js" "sidebar/util/*.js"
], ],
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
* @prop {string} [id] * @prop {string} [id]
* @prop {string[]} [references] * @prop {string[]} [references]
* @prop {string} created * @prop {string} created
* @prop {string} group
* @prop {string} updated * @prop {string} updated
* @prop {string[]} tags * @prop {string[]} tags
* @prop {string} text * @prop {string} text
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment