@@ -412,21 +412,58 @@ function checkSymbol({
412412 // but not
413413 // { a?: React.ElementType, b: React.ReactElement }
414414 // get around this by not using the TypeChecker
415- if (
416- declaration &&
417- ts . isPropertySignature ( declaration ) &&
418- declaration . type &&
419- ts . isTypeReferenceNode ( declaration . type )
420- ) {
421- const name = declaration . type . typeName . getText ( ) ;
422- if (
423- name === 'React.ElementType' ||
424- name === 'React.ComponentType' ||
425- name === 'React.JSXElementConstructor' ||
426- name === 'React.ReactElement'
427- ) {
415+ if ( declaration && ts . isPropertySignature ( declaration ) && declaration . type ) {
416+ // Helper to check if a type node is a React element type reference
417+ const getElementTypeName = ( typeNode : ts . TypeNode ) : string | null => {
418+ if ( ts . isTypeReferenceNode ( typeNode ) ) {
419+ const name = typeNode . typeName . getText ( ) ;
420+ if (
421+ name === 'React.ElementType' ||
422+ name === 'React.ComponentType' ||
423+ name === 'React.JSXElementConstructor' ||
424+ name === 'React.ReactElement'
425+ ) {
426+ return name ;
427+ }
428+ }
429+ return null ;
430+ } ;
431+
432+ // Check for direct type reference (e.g., `prop: React.ElementType`)
433+ let elementTypeName = getElementTypeName ( declaration . type ) ;
434+
435+ // Also check for union types like `React.ElementType | undefined`
436+ // but NOT for unions with other types like `string | React.ReactElement | undefined`
437+ if ( ! elementTypeName && ts . isUnionTypeNode ( declaration . type ) ) {
438+ let foundElementType : string | null = null ;
439+ let hasOtherNonUndefinedTypes = false ;
440+
441+ for ( const typeNode of declaration . type . types ) {
442+ const name = getElementTypeName ( typeNode ) ;
443+ if ( name ) {
444+ foundElementType = name ;
445+ } else if (
446+ // Check if this is an undefined type (keyword or literal)
447+ ! (
448+ typeNode . kind === ts . SyntaxKind . UndefinedKeyword ||
449+ ( ts . isLiteralTypeNode ( typeNode ) &&
450+ typeNode . literal . kind === ts . SyntaxKind . UndefinedKeyword )
451+ )
452+ ) {
453+ // Found a type that's neither an element type nor undefined
454+ hasOtherNonUndefinedTypes = true ;
455+ }
456+ }
457+
458+ // Only use the element type if the union doesn't have other non-undefined types
459+ if ( foundElementType && ! hasOtherNonUndefinedTypes ) {
460+ elementTypeName = foundElementType ;
461+ }
462+ }
463+
464+ if ( elementTypeName ) {
428465 const elementNode = createElementType ( {
429- elementType : name === 'React.ReactElement' ? 'element' : 'elementType' ,
466+ elementType : elementTypeName === 'React.ReactElement' ? 'element' : 'elementType' ,
430467 jsDoc,
431468 } ) ;
432469
0 commit comments