From c84e5fc0426a92f5bd368b6ddeeeabf96362c174 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Wed, 16 Mar 2022 19:53:28 -0700 Subject: [PATCH] Core data: Fix minor type-related issues. Part of #39211 Fixes minor type-related issues that are mostly problems with JSDoc type signatures. In a couple of places a safe-defaulting fallback has been added where the existing JS code assumes the presence of nullable data. --- docs/reference-guides/data/data-core.md | 6 ++--- packages/core-data/README.md | 6 ++--- packages/core-data/src/entities.js | 2 +- packages/core-data/src/entity-provider.js | 2 ++ .../core-data/src/entity-types/sidebar.ts | 3 +-- .../core-data/src/hooks/use-entity-record.ts | 2 +- .../core-data/src/hooks/use-entity-records.ts | 12 ++++++---- .../core-data/src/queried-data/actions.js | 8 +++---- .../src/queried-data/get-query-parts.js | 10 ++++---- .../core-data/src/queried-data/reducer.js | 10 ++++---- packages/core-data/src/reducer.js | 24 +++++++++---------- packages/core-data/src/selectors.js | 24 +++++++++---------- 12 files changed, 57 insertions(+), 52 deletions(-) diff --git a/docs/reference-guides/data/data-core.md b/docs/reference-guides/data/data-core.md index da5dd9af47e122..3353b1dd41c248 100644 --- a/docs/reference-guides/data/data-core.md +++ b/docs/reference-guides/data/data-core.md @@ -127,7 +127,7 @@ _Parameters_ - _state_ `Object`: State tree. - _kind_ `string`: Entity kind. - _name_ `string`: Entity name. -- _recordId_ `number`: Record ID. +- _recordId_ `number|string`: Record ID. _Returns_ @@ -220,7 +220,7 @@ _Parameters_ _Returns_ -- `Object?`: Record. +- `Object|undefined`: Record. ### getEntityRecordEdits @@ -531,7 +531,7 @@ _Parameters_ - _state_ `Object`: State tree. - _kind_ `string`: Entity kind. - _name_ `string`: Entity name. -- _recordId_ `number`: Record ID. +- _recordId_ `number|string`: Record ID. _Returns_ diff --git a/packages/core-data/README.md b/packages/core-data/README.md index d19c0a11ad0b01..aa26746a4df95f 100644 --- a/packages/core-data/README.md +++ b/packages/core-data/README.md @@ -374,7 +374,7 @@ _Parameters_ - _state_ `Object`: State tree. - _kind_ `string`: Entity kind. - _name_ `string`: Entity name. -- _recordId_ `number`: Record ID. +- _recordId_ `number|string`: Record ID. _Returns_ @@ -467,7 +467,7 @@ _Parameters_ _Returns_ -- `Object?`: Record. +- `Object|undefined`: Record. ### getEntityRecordEdits @@ -778,7 +778,7 @@ _Parameters_ - _state_ `Object`: State tree. - _kind_ `string`: Entity kind. - _name_ `string`: Entity name. -- _recordId_ `number`: Record ID. +- _recordId_ `number|string`: Record ID. _Returns_ diff --git a/packages/core-data/src/entities.js b/packages/core-data/src/entities.js index be2186d9353862..09731d54841fc2 100644 --- a/packages/core-data/src/entities.js +++ b/packages/core-data/src/entities.js @@ -308,7 +308,7 @@ export const getMethodName = ( * * @param {string} kind Kind * - * @return {Array} Entities + * @return {(thunkArgs: object) => Promise} Entities */ export const getOrLoadEntitiesConfig = ( kind ) => async ( { select, diff --git a/packages/core-data/src/entity-provider.js b/packages/core-data/src/entity-provider.js index 82e6b5b7f03f66..01a3e50be811a8 100644 --- a/packages/core-data/src/entity-provider.js +++ b/packages/core-data/src/entity-provider.js @@ -15,6 +15,8 @@ import { parse, __unstableSerializeAndClean } from '@wordpress/blocks'; */ import { STORE_NAME } from './name'; +/** @typedef {import('@wordpress/blocks').WPBlock} WPBlock */ + const EMPTY_ARRAY = []; /** diff --git a/packages/core-data/src/entity-types/sidebar.ts b/packages/core-data/src/entity-types/sidebar.ts index cbfceefd901db7..177d8f651c571a 100644 --- a/packages/core-data/src/entity-types/sidebar.ts +++ b/packages/core-data/src/entity-types/sidebar.ts @@ -1,7 +1,6 @@ /** * Internal dependencies */ -import type { Widget } from './widget'; import type { Context, OmitNevers } from './helpers'; import type { BaseEntityRecords as _BaseEntityRecords } from './base-entity-records'; @@ -48,7 +47,7 @@ declare module './base-entity-records' { /** * Nested widgets. */ - widgets: ( Widget< C > | string )[]; + widgets: ( BaseEntityRecords.Widget< C > | string )[]; } } } diff --git a/packages/core-data/src/hooks/use-entity-record.ts b/packages/core-data/src/hooks/use-entity-record.ts index 809a7d70190d8c..184c59ba6bac97 100644 --- a/packages/core-data/src/hooks/use-entity-record.ts +++ b/packages/core-data/src/hooks/use-entity-record.ts @@ -3,7 +3,7 @@ */ import useQuerySelect from './use-query-select'; import { store as coreStore } from '../'; -import { Status } from './constants'; +import type { Status } from './constants'; interface EntityRecordResolution< RecordType > { /** The requested entity record */ diff --git a/packages/core-data/src/hooks/use-entity-records.ts b/packages/core-data/src/hooks/use-entity-records.ts index 5c593cdb7722ad..8b88fb2f662f7a 100644 --- a/packages/core-data/src/hooks/use-entity-records.ts +++ b/packages/core-data/src/hooks/use-entity-records.ts @@ -8,7 +8,7 @@ import { addQueryArgs } from '@wordpress/url'; */ import useQuerySelect from './use-query-select'; import { store as coreStore } from '../'; -import { Status } from './constants'; +import type { Status } from './constants'; interface EntityRecordsResolution< RecordType > { /** The requested entity record */ @@ -29,6 +29,11 @@ interface EntityRecordsResolution< RecordType > { } interface Options { + /** + * Whether to run the query or short-circuit and return null. + * + * @default true + */ enabled: boolean; } @@ -39,7 +44,6 @@ interface Options { * @param name Name of the requested entities. * @param queryArgs HTTP query for the requested entities. * @param options Hook options. - * @param [options.enabled=true] Whether to run the query or short-circuit and return null. Defaults to true. * @example * ```js * import { useEntityRecord } from '@wordpress/core-data'; @@ -68,13 +72,13 @@ interface Options { * application, the list of records and the resolution details will be retrieved from * the store state using `getEntityRecords()`, or resolved if missing. * - * @return {EntityRecordsResolution} Entity records data. + * @return Entity records data. * @template RecordType */ export default function __experimentalUseEntityRecords< RecordType >( kind: string, name: string, - queryArgs: unknown = {}, + queryArgs: Record< string, unknown > = {}, options: Options = { enabled: true } ): EntityRecordsResolution< RecordType > { // Serialize queryArgs to a string that can be safely used as a React dep. diff --git a/packages/core-data/src/queried-data/actions.js b/packages/core-data/src/queried-data/actions.js index 15984e8ac441df..7236b4db617a4f 100644 --- a/packages/core-data/src/queried-data/actions.js +++ b/packages/core-data/src/queried-data/actions.js @@ -23,10 +23,10 @@ export function receiveItems( items, edits ) { * Returns an action object used in signalling that entity records have been * deleted and they need to be removed from entities state. * - * @param {string} kind Kind of the removed entities. - * @param {string} name Name of the removed entities. - * @param {Array|number} records Record IDs of the removed entities. - * @param {boolean} invalidateCache Controls whether we want to invalidate the cache. + * @param {string} kind Kind of the removed entities. + * @param {string} name Name of the removed entities. + * @param {Array|number|string} records Record IDs of the removed entities. + * @param {boolean} invalidateCache Controls whether we want to invalidate the cache. * @return {Object} Action object. */ export function removeItems( kind, name, records, invalidateCache = false ) { diff --git a/packages/core-data/src/queried-data/get-query-parts.js b/packages/core-data/src/queried-data/get-query-parts.js index d46079dfa5d809..90ca024f80a414 100644 --- a/packages/core-data/src/queried-data/get-query-parts.js +++ b/packages/core-data/src/queried-data/get-query-parts.js @@ -70,19 +70,19 @@ export function getQueryParts( query ) { // While in theory, we could exclude "_fields" from the stableKey // because two request with different fields have the same results // We're not able to ensure that because the server can decide to omit - // fields from the response even if we explicitely asked for it. + // fields from the response even if we explicitly asked for it. // Example: Asking for titles in posts without title support. if ( key === '_fields' ) { - parts.fields = getNormalizedCommaSeparable( value ); + parts.fields = getNormalizedCommaSeparable( value ) ?? []; // Make sure to normalize value for `stableKey` value = parts.fields.join(); } // Two requests with different include values cannot have same results. if ( key === 'include' ) { - parts.include = getNormalizedCommaSeparable( value ).map( - Number - ); + parts.include = ( + getNormalizedCommaSeparable( value ) ?? [] + ).map( Number ); // Normalize value for `stableKey`. value = parts.include.join(); } diff --git a/packages/core-data/src/queried-data/reducer.js b/packages/core-data/src/queried-data/reducer.js index 792b70c049ac87..bfb17045626d56 100644 --- a/packages/core-data/src/queried-data/reducer.js +++ b/packages/core-data/src/queried-data/reducer.js @@ -51,7 +51,7 @@ export function getMergedItemIds( itemIds, nextItemIds, page, perPage ) { // If later page has already been received, default to the larger known // size of the existing array, else calculate as extending the existing. const size = Math.max( - itemIds.length, + itemIds?.length ?? 0, nextItemIdsStartIndex + nextItemIds.length ); @@ -66,7 +66,7 @@ export function getMergedItemIds( itemIds, nextItemIds, page, perPage ) { mergedItemIds[ i ] = isInNextItemsRange ? nextItemIds[ i - nextItemIdsStartIndex ] - : itemIds[ i ]; + : itemIds?.[ i ]; } return mergedItemIds; @@ -116,10 +116,10 @@ export function items( state = {}, action ) { * In such cases, completeness is used as an indication of whether it would be * safe to use queried data for a non-`_fields`-limited request. * - * @param {Object} state Current state. - * @param {Object} action Dispatched action. + * @param {Object>} state Current state. + * @param {Object} action Dispatched action. * - * @return {Object} Next state. + * @return {Object>} Next state. */ export function itemIsComplete( state = {}, action ) { switch ( action.type ) { diff --git a/packages/core-data/src/reducer.js b/packages/core-data/src/reducer.js index 0d3f70a08daf9d..0c901c8ab7a2fc 100644 --- a/packages/core-data/src/reducer.js +++ b/packages/core-data/src/reducer.js @@ -105,10 +105,10 @@ export function taxonomies( state = [], action ) { /** * Reducer managing the current theme. * - * @param {string} state Current state. - * @param {Object} action Dispatched action. + * @param {string|undefined} state Current state. + * @param {Object} action Dispatched action. * - * @return {string} Updated state. + * @return {string|undefined} Updated state. */ export function currentTheme( state = undefined, action ) { switch ( action.type ) { @@ -122,10 +122,10 @@ export function currentTheme( state = undefined, action ) { /** * Reducer managing the current global styles id. * - * @param {string} state Current state. - * @param {Object} action Dispatched action. + * @param {string|undefined} state Current state. + * @param {Object} action Dispatched action. * - * @return {string} Updated state. + * @return {string|undefined} Updated state. */ export function currentGlobalStylesId( state = undefined, action ) { switch ( action.type ) { @@ -139,10 +139,10 @@ export function currentGlobalStylesId( state = undefined, action ) { /** * Reducer managing the theme base global styles. * - * @param {string} state Current state. - * @param {Object} action Dispatched action. + * @param {Record} state Current state. + * @param {Object} action Dispatched action. * - * @return {string} Updated state. + * @return {Record} Updated state. */ export function themeBaseGlobalStyles( state = {}, action ) { switch ( action.type ) { @@ -159,10 +159,10 @@ export function themeBaseGlobalStyles( state = {}, action ) { /** * Reducer managing the theme global styles variations. * - * @param {string} state Current state. - * @param {Object} action Dispatched action. + * @param {Record} state Current state. + * @param {Object} action Dispatched action. * - * @return {string} Updated state. + * @return {Record} Updated state. */ export function themeGlobalStyleVariations( state = {}, action ) { switch ( action.type ) { diff --git a/packages/core-data/src/selectors.js b/packages/core-data/src/selectors.js index fb6a311be00991..01dc3024152afd 100644 --- a/packages/core-data/src/selectors.js +++ b/packages/core-data/src/selectors.js @@ -165,7 +165,7 @@ export function getEntityConfig( state, kind, name ) { * @param {number} key Record's key * @param {?Object} query Optional query. * - * @return {Object?} Record. + * @return {Object|undefined} Record. */ export const getEntityRecord = createSelector( ( state, kind, name, key, query ) => { @@ -191,7 +191,7 @@ export const getEntityRecord = createSelector( const item = queriedState.items[ context ]?.[ key ]; if ( item && query._fields ) { const filteredItem = {}; - const fields = getNormalizedCommaSeparable( query._fields ); + const fields = getNormalizedCommaSeparable( query._fields ) ?? []; for ( let f = 0; f < fields.length; f++ ) { const field = fields[ f ].split( '.' ); const value = get( item, field ); @@ -520,10 +520,10 @@ export function hasEditsForEntityRecord( state, kind, name, recordId ) { /** * Returns the specified entity record, merged with its edits. * - * @param {Object} state State tree. - * @param {string} kind Entity kind. - * @param {string} name Entity name. - * @param {number} recordId Record ID. + * @param {Object} state State tree. + * @param {string} kind Entity kind. + * @param {string} name Entity name. + * @param {number|string} recordId Record ID. * * @return {Object?} The entity record, merged with its edits. */ @@ -579,10 +579,10 @@ export function isAutosavingEntityRecord( state, kind, name, recordId ) { /** * Returns true if the specified entity record is saving, and false otherwise. * - * @param {Object} state State tree. - * @param {string} kind Entity kind. - * @param {string} name Entity name. - * @param {number} recordId Record ID. + * @param {Object} state State tree. + * @param {string} kind Entity kind. + * @param {string} name Entity name. + * @param {number|string} recordId Record ID. * * @return {boolean} Whether the entity record is saving or not. */ @@ -938,7 +938,7 @@ export function __experimentalGetTemplateForLink( state, link ) { * * @param {Object} state Editor state. * - * @return {Object?} The Global Styles object. + * @return {Object|null} The Global Styles object. */ export function __experimentalGetCurrentThemeBaseGlobalStyles( state ) { const currentTheme = getCurrentTheme( state ); @@ -953,7 +953,7 @@ export function __experimentalGetCurrentThemeBaseGlobalStyles( state ) { * * @param {Object} state Data state. * - * @return {string} The current global styles ID. + * @return {string|null} The current global styles ID. */ export function __experimentalGetCurrentThemeGlobalStylesVariations( state ) { const currentTheme = getCurrentTheme( state );