From b68c05dd14c11739783d0f673c60ace7211a9a2c Mon Sep 17 00:00:00 2001 From: Infinite-Null Date: Wed, 22 Apr 2026 18:29:09 +0530 Subject: [PATCH 1/6] Enhance function checks for TypeScript declarations --- .../lib/get-intermediate-representation.js | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/docgen/lib/get-intermediate-representation.js b/packages/docgen/lib/get-intermediate-representation.js index 9f49fc4d4f93a2..fab68e8796111a 100644 --- a/packages/docgen/lib/get-intermediate-representation.js +++ b/packages/docgen/lib/get-intermediate-representation.js @@ -15,6 +15,9 @@ const hasClassWithName = ( node, name ) => const hasFunctionWithName = ( node, name ) => node.type === 'FunctionDeclaration' && node.id.name === name; +const hasTSDeclareFunction = ( node, name ) => + node.type === 'TSDeclareFunction' && node.id?.name === name; + const hasVariableWithName = ( node, name ) => node.type === 'VariableDeclaration' && node.declarations.some( ( declaration ) => { @@ -32,6 +35,8 @@ const hasNamedExportWithName = ( node, name ) => node.type === 'ExportNamedDeclaration' && ( ( node.declaration && hasClassWithName( node.declaration, name ) ) || ( node.declaration && hasFunctionWithName( node.declaration, name ) ) || + ( node.declaration && + hasTSDeclareFunction( node.declaration, name ) ) || ( node.declaration && hasVariableWithName( node.declaration, name ) ) ); const hasImportWithName = ( node, name ) => @@ -96,14 +101,18 @@ const getJSDoc = ( token, entry, ast, parseDependency ) => { hasImportWithName( node, entry.localName ) ); } ); - if ( candidates.length !== 1 ) { + if ( candidates.length === 0 ) { return doc; } - const node = candidates[ 0 ]; - if ( isImportDeclaration( node ) ) { - doc = getJSDocFromDependency( node, entry, parseDependency ); - } else { - doc = getJSDocFromToken( node ); + for ( const node of candidates ) { + if ( isImportDeclaration( node ) ) { + doc = getJSDocFromDependency( node, entry, parseDependency ); + } else { + doc = getJSDocFromToken( node ); + } + if ( doc !== undefined ) { + return doc; + } } return doc; } From 1dc05c3a2bc1657fd3b14b3e044be2c24d5c6b11 Mon Sep 17 00:00:00 2001 From: Infinite-Null Date: Thu, 23 Apr 2026 19:33:26 +0530 Subject: [PATCH 2/6] Add TypeScript function overloads tests and enhance documentation for registerBlockType --- packages/blocks/README.md | 26 ++++++++++++++++++- .../test/get-intermediate-representation.js | 24 +++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/packages/blocks/README.md b/packages/blocks/README.md index 8c277868a03321..1e0fe8b5f7dba7 100644 --- a/packages/blocks/README.md +++ b/packages/blocks/README.md @@ -607,7 +607,31 @@ _Parameters_ ### registerBlockType -Undocumented declaration. +Registers a new block provided a unique name and an object defining its behavior. Once registered, the block is made available as an option to any editor interface where blocks are implemented. + +For more in-depth information on registering a custom block see the [Create a block tutorial](https://developer.wordpress.org/block-editor/getting-started/create-block/). + +_Usage_ + +```js +import { __ } from '@wordpress/i18n'; +import { registerBlockType } from '@wordpress/blocks'; + +registerBlockType( 'namespace/block-name', { + title: __( 'My First Block' ), + edit: () =>
{ __( 'Hello from the editor!' ) }
, + save: () =>
Hello from the saved content!
, +} ); +``` + +_Parameters_ + +- _blockNameOrMetadata_ `BlockConfiguration< Attributes >`: Block type name or its metadata. +- _settings_ `Partial< BlockConfiguration< Attributes > >`: Block settings. + +_Returns_ + +- `BlockType | undefined`: The block, if it has been successfully registered; otherwise `undefined`. ### registerBlockVariation diff --git a/packages/docgen/test/get-intermediate-representation.js b/packages/docgen/test/get-intermediate-representation.js index e61f3101ad8438..4e814439a4f040 100644 --- a/packages/docgen/test/get-intermediate-representation.js +++ b/packages/docgen/test/get-intermediate-representation.js @@ -662,6 +662,30 @@ describe( 'Intermediate Representation', () => { } ); } ); + describe( 'TypeScript function overloads', () => { + it( 'extracts JSDoc with tags from first overload signature', () => + expect( + parse( ` + /** + * Registers a new block. + * @param blockNameOrMetadata Block type name or its metadata. + * @param settings Block settings. + * @return The block, if registered; otherwise undefined. + */ + export function registerBlockType( blockNameOrMetadata: object, settings?: object ): object | undefined; + export function registerBlockType( blockNameOrMetadata: string, settings: object ): object | undefined; + export function registerBlockType( blockNameOrMetadata: string | object, settings?: object ): object | undefined { + return undefined; + } + ` ) + ).toEqual( [ + expect.objectContaining( { + description: 'Registers a new block.', + name: 'registerBlockType', + } ), + ] ) ); + } ); + describe( 'JSDoc in module dependency through import', () => { describe( 'default export', () => { it( 'default import', () => From d88fdadb481bd85b1a434b243c06a1469f2a80f3 Mon Sep 17 00:00:00 2001 From: Infinite-Null Date: Tue, 28 Apr 2026 01:07:33 +0530 Subject: [PATCH 3/6] Enhance TypeScript function overload handling in JSDoc extraction and tests --- .../lib/get-intermediate-representation.js | 13 ++++++++++++- packages/docgen/lib/get-jsdoc-from-token.js | 12 ++++++++---- .../test/get-intermediate-representation.js | 16 +++++++++++++++- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/packages/docgen/lib/get-intermediate-representation.js b/packages/docgen/lib/get-intermediate-representation.js index fab68e8796111a..25143eda6a8e7d 100644 --- a/packages/docgen/lib/get-intermediate-representation.js +++ b/packages/docgen/lib/get-intermediate-representation.js @@ -18,6 +18,14 @@ const hasFunctionWithName = ( node, name ) => const hasTSDeclareFunction = ( node, name ) => node.type === 'TSDeclareFunction' && node.id?.name === name; +// Matches the concrete implementation node (FunctionDeclaration with a body), +// as opposed to a TypeScript overload signature (TSDeclareFunction). +const hasImplementationWithName = ( node, name ) => + hasFunctionWithName( node, name ) || + ( node.type === 'ExportNamedDeclaration' && + node.declaration && + hasFunctionWithName( node.declaration, name ) ); + const hasVariableWithName = ( node, name ) => node.type === 'VariableDeclaration' && node.declarations.some( ( declaration ) => { @@ -104,11 +112,14 @@ const getJSDoc = ( token, entry, ast, parseDependency ) => { if ( candidates.length === 0 ) { return doc; } + const implementationNode = candidates.find( ( node ) => + hasImplementationWithName( node, entry.localName ) + ); for ( const node of candidates ) { if ( isImportDeclaration( node ) ) { doc = getJSDocFromDependency( node, entry, parseDependency ); } else { - doc = getJSDocFromToken( node ); + doc = getJSDocFromToken( node, implementationNode ?? node ); } if ( doc !== undefined ) { return doc; diff --git a/packages/docgen/lib/get-jsdoc-from-token.js b/packages/docgen/lib/get-jsdoc-from-token.js index 4b364c9a561b08..8cfad5da1e94c9 100644 --- a/packages/docgen/lib/get-jsdoc-from-token.js +++ b/packages/docgen/lib/get-jsdoc-from-token.js @@ -14,10 +14,14 @@ const getTypeAnnotation = require( './get-type-annotation' ); * a object representing the leading JSDoc comment of the token, * if any. * - * @param {Object} token Espree token. + * @param {Object} token Espree token to extract the leading JSDoc comment from. + * @param {Object} [typeAnnotationToken] Espree token to use for type inference. Defaults to `token`. + * Pass the function implementation node when the JSDoc lives on + * an overload signature so that inferred types reflect the + * implementation's parameter/return types. * @return {Object} Object representing the JSDoc comment. */ -module.exports = ( token ) => { +module.exports = ( token, typeAnnotationToken = token ) => { let jsdoc; const comments = getLeadingComments( token ); if ( comments && /^\*\r?\n/.test( comments ) ) { @@ -44,7 +48,7 @@ module.exports = ( token ) => { return { ...tag, - type: getTypeAnnotation( tag, token, index ), + type: getTypeAnnotation( tag, typeAnnotationToken, index ), description: tag.description === '\n' ? tag.description.trim() @@ -55,7 +59,7 @@ module.exports = ( token ) => { if ( jsdoc.tags.length === 0 ) { const potentialTypeAnnotation = getTypeAnnotation( { tag: 'type' }, - token, + typeAnnotationToken, 0 ); if ( potentialTypeAnnotation ) { diff --git a/packages/docgen/test/get-intermediate-representation.js b/packages/docgen/test/get-intermediate-representation.js index 4e814439a4f040..5ff87191cfc1f2 100644 --- a/packages/docgen/test/get-intermediate-representation.js +++ b/packages/docgen/test/get-intermediate-representation.js @@ -663,7 +663,7 @@ describe( 'Intermediate Representation', () => { } ); describe( 'TypeScript function overloads', () => { - it( 'extracts JSDoc with tags from first overload signature', () => + it( 'extracts description from first overload signature and infers types from the implementation', () => expect( parse( ` /** @@ -682,6 +682,20 @@ describe( 'Intermediate Representation', () => { expect.objectContaining( { description: 'Registers a new block.', name: 'registerBlockType', + tags: expect.arrayContaining( [ + expect.objectContaining( { + tag: 'param', + name: 'blockNameOrMetadata', + // Type comes from the implementation signature (string | object), + // not the first overload signature (object). + type: 'string | object', + } ), + expect.objectContaining( { + tag: 'return', + // Return type comes from the implementation signature. + type: 'object | undefined', + } ), + ] ), } ), ] ) ); } ); From b6c42674cd46e5a82c8394e9fe5ad6fd0d81dd74 Mon Sep 17 00:00:00 2001 From: Infinite-Null Date: Tue, 28 Apr 2026 18:31:43 +0530 Subject: [PATCH 4/6] Fix formatting in JSDoc parameter description for token extraction --- packages/docgen/lib/get-jsdoc-from-token.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docgen/lib/get-jsdoc-from-token.js b/packages/docgen/lib/get-jsdoc-from-token.js index 8cfad5da1e94c9..7bfe5141e55a0a 100644 --- a/packages/docgen/lib/get-jsdoc-from-token.js +++ b/packages/docgen/lib/get-jsdoc-from-token.js @@ -14,7 +14,7 @@ const getTypeAnnotation = require( './get-type-annotation' ); * a object representing the leading JSDoc comment of the token, * if any. * - * @param {Object} token Espree token to extract the leading JSDoc comment from. + * @param {Object} token Espree token to extract the leading JSDoc comment from. * @param {Object} [typeAnnotationToken] Espree token to use for type inference. Defaults to `token`. * Pass the function implementation node when the JSDoc lives on * an overload signature so that inferred types reflect the From a4ce6bd956c893f54f4fa05897e896a79b707410 Mon Sep 17 00:00:00 2001 From: Infinite-Null Date: Tue, 28 Apr 2026 19:00:13 +0530 Subject: [PATCH 5/6] Enhance JSDoc extraction for TypeScript function overloads and add corresponding tests Co-authored-by: Copilot --- packages/blocks/README.md | 2 +- packages/compose/README.md | 14 +++++------ .../lib/get-intermediate-representation.js | 1 + .../test/get-intermediate-representation.js | 23 +++++++++++++++++++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/packages/blocks/README.md b/packages/blocks/README.md index 1e0fe8b5f7dba7..e04239e0e78c75 100644 --- a/packages/blocks/README.md +++ b/packages/blocks/README.md @@ -626,7 +626,7 @@ registerBlockType( 'namespace/block-name', { _Parameters_ -- _blockNameOrMetadata_ `BlockConfiguration< Attributes >`: Block type name or its metadata. +- _blockNameOrMetadata_ `string | BlockConfiguration< Attributes >`: Block type name or its metadata. - _settings_ `Partial< BlockConfiguration< Attributes > >`: Block settings. _Returns_ diff --git a/packages/compose/README.md b/packages/compose/README.md index 0908e8e559948c..57d1ed4fb53056 100644 --- a/packages/compose/README.md +++ b/packages/compose/README.md @@ -394,17 +394,17 @@ _Returns_ ### useInstanceId -Provides a unique instance ID. +Specify the useInstanceId _function_ signatures. -_Parameters_ +More accurately, useInstanceId distinguishes between three different signatures: -- _object_ `object`: Object reference to create an id for. -- _prefix_ `[string]`: Prefix for the unique id. -- _preferredId_ `[string | number]`: Default ID to use. +1. When only object is given, the returned value is a number +2. When object and prefix is given, the returned value is a string +3. When preferredId is given, the returned value is the type of preferredId -_Returns_ +_Parameters_ -- `string | number`: The unique instance id. +- _object_ `object`: Object reference to create an id for. ### useIsomorphicLayoutEffect diff --git a/packages/docgen/lib/get-intermediate-representation.js b/packages/docgen/lib/get-intermediate-representation.js index 25143eda6a8e7d..cf19c57eae66ea 100644 --- a/packages/docgen/lib/get-intermediate-representation.js +++ b/packages/docgen/lib/get-intermediate-representation.js @@ -104,6 +104,7 @@ const getJSDoc = ( token, entry, ast, parseDependency ) => { return ( hasClassWithName( node, entry.localName ) || hasFunctionWithName( node, entry.localName ) || + hasTSDeclareFunction( node, entry.localName ) || hasVariableWithName( node, entry.localName ) || hasNamedExportWithName( node, entry.localName ) || hasImportWithName( node, entry.localName ) diff --git a/packages/docgen/test/get-intermediate-representation.js b/packages/docgen/test/get-intermediate-representation.js index 5ff87191cfc1f2..88a7a8c0747b54 100644 --- a/packages/docgen/test/get-intermediate-representation.js +++ b/packages/docgen/test/get-intermediate-representation.js @@ -698,6 +698,29 @@ describe( 'Intermediate Representation', () => { ] ), } ), ] ) ); + + it( 'extracts JSDoc from non-exported overload signatures exported via export { }', () => + expect( + parse( ` + /** + * My overloaded function. + * @param a The argument. + * @return The result. + */ + function myDeclaration( a: string ): string; + function myDeclaration( a: number ): number; + function myDeclaration( a: string | number ): string | number { + return a; + } + + export { myDeclaration }; + ` ) + ).toEqual( [ + expect.objectContaining( { + description: 'My overloaded function.', + name: 'myDeclaration', + } ), + ] ) ); } ); describe( 'JSDoc in module dependency through import', () => { From 5ebedb03c73e5ff8009cfcb137bbbb77e0218034 Mon Sep 17 00:00:00 2001 From: Infinite-Null Date: Tue, 28 Apr 2026 19:51:19 +0530 Subject: [PATCH 6/6] Remove outdated comments regarding TypeScript function overloads in implementation checks --- packages/docgen/lib/get-intermediate-representation.js | 2 -- packages/docgen/test/get-intermediate-representation.js | 3 --- 2 files changed, 5 deletions(-) diff --git a/packages/docgen/lib/get-intermediate-representation.js b/packages/docgen/lib/get-intermediate-representation.js index cf19c57eae66ea..05705718e8d9b5 100644 --- a/packages/docgen/lib/get-intermediate-representation.js +++ b/packages/docgen/lib/get-intermediate-representation.js @@ -18,8 +18,6 @@ const hasFunctionWithName = ( node, name ) => const hasTSDeclareFunction = ( node, name ) => node.type === 'TSDeclareFunction' && node.id?.name === name; -// Matches the concrete implementation node (FunctionDeclaration with a body), -// as opposed to a TypeScript overload signature (TSDeclareFunction). const hasImplementationWithName = ( node, name ) => hasFunctionWithName( node, name ) || ( node.type === 'ExportNamedDeclaration' && diff --git a/packages/docgen/test/get-intermediate-representation.js b/packages/docgen/test/get-intermediate-representation.js index 88a7a8c0747b54..109bc7ecf01815 100644 --- a/packages/docgen/test/get-intermediate-representation.js +++ b/packages/docgen/test/get-intermediate-representation.js @@ -686,13 +686,10 @@ describe( 'Intermediate Representation', () => { expect.objectContaining( { tag: 'param', name: 'blockNameOrMetadata', - // Type comes from the implementation signature (string | object), - // not the first overload signature (object). type: 'string | object', } ), expect.objectContaining( { tag: 'return', - // Return type comes from the implementation signature. type: 'object | undefined', } ), ] ),