diff --git a/docs/pages/base-ui/api/button.json b/docs/pages/base-ui/api/button.json index d72db39a0f1984..54360651da6723 100644 --- a/docs/pages/base-ui/api/button.json +++ b/docs/pages/base-ui/api/button.json @@ -1,11 +1,6 @@ { "props": { - "action": { - "type": { - "name": "union", - "description": "func
| { current?: { focusVisible: func } }" - } - }, + "action": { "type": { "name": "custom", "description": "ref" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "focusableWhenDisabled": { "type": { "name": "bool" }, "default": "false" }, "slotProps": { diff --git a/docs/pages/base-ui/api/tab.json b/docs/pages/base-ui/api/tab.json index 16d505a50d9b90..93500b1926bae0 100644 --- a/docs/pages/base-ui/api/tab.json +++ b/docs/pages/base-ui/api/tab.json @@ -1,11 +1,6 @@ { "props": { - "action": { - "type": { - "name": "union", - "description": "func
| { current?: { focusVisible: func } }" - } - }, + "action": { "type": { "name": "custom", "description": "ref" } }, "disabled": { "type": { "name": "bool" }, "default": "false" }, "onChange": { "type": { "name": "func" } }, "slotProps": { diff --git a/docs/pages/joy-ui/api/button.json b/docs/pages/joy-ui/api/button.json index 0f5a178a82b022..c5e61d3252e72e 100644 --- a/docs/pages/joy-ui/api/button.json +++ b/docs/pages/joy-ui/api/button.json @@ -1,11 +1,6 @@ { "props": { - "action": { - "type": { - "name": "union", - "description": "func
| { current?: { focusVisible: func } }" - } - }, + "action": { "type": { "name": "custom", "description": "ref" } }, "color": { "type": { "name": "union", diff --git a/docs/pages/joy-ui/api/icon-button.json b/docs/pages/joy-ui/api/icon-button.json index 7e938464261723..04d01296bbe717 100644 --- a/docs/pages/joy-ui/api/icon-button.json +++ b/docs/pages/joy-ui/api/icon-button.json @@ -1,11 +1,6 @@ { "props": { - "action": { - "type": { - "name": "union", - "description": "func
| { current?: { focusVisible: func } }" - } - }, + "action": { "type": { "name": "custom", "description": "ref" } }, "color": { "type": { "name": "union", diff --git a/docs/pages/joy-ui/api/list-item-button.json b/docs/pages/joy-ui/api/list-item-button.json index 88108c69a213d6..2757a522f168e3 100644 --- a/docs/pages/joy-ui/api/list-item-button.json +++ b/docs/pages/joy-ui/api/list-item-button.json @@ -1,11 +1,6 @@ { "props": { - "action": { - "type": { - "name": "union", - "description": "func
| { current?: { focusVisible: func } }" - } - }, + "action": { "type": { "name": "custom", "description": "ref" } }, "autoFocus": { "type": { "name": "bool" }, "default": "false" }, "children": { "type": { "name": "node" } }, "color": { diff --git a/docs/pages/joy-ui/api/select.json b/docs/pages/joy-ui/api/select.json index af8f6611339328..ef30d73f5dc632 100644 --- a/docs/pages/joy-ui/api/select.json +++ b/docs/pages/joy-ui/api/select.json @@ -1,11 +1,6 @@ { "props": { - "action": { - "type": { - "name": "union", - "description": "func
| { current?: { focusVisible: func } }" - } - }, + "action": { "type": { "name": "custom", "description": "ref" } }, "autoFocus": { "type": { "name": "bool" } }, "color": { "type": { diff --git a/docs/pages/joy-ui/api/tab.json b/docs/pages/joy-ui/api/tab.json index 43cf0eca137669..c8b5c92b395664 100644 --- a/docs/pages/joy-ui/api/tab.json +++ b/docs/pages/joy-ui/api/tab.json @@ -1,11 +1,6 @@ { "props": { - "action": { - "type": { - "name": "union", - "description": "func
| { current?: { focusVisible: func } }" - } - }, + "action": { "type": { "name": "custom", "description": "ref" } }, "color": { "type": { "name": "union", diff --git a/docs/pages/material-ui/api/button-base.json b/docs/pages/material-ui/api/button-base.json index e383c1ff531d6d..fee7a61f961964 100644 --- a/docs/pages/material-ui/api/button-base.json +++ b/docs/pages/material-ui/api/button-base.json @@ -20,12 +20,7 @@ "additionalInfo": { "sx": true } }, "TouchRippleProps": { "type": { "name": "object" } }, - "touchRippleRef": { - "type": { - "name": "union", - "description": "func
| { current?: { pulsate: func, start: func, stop: func } }" - } - } + "touchRippleRef": { "type": { "name": "custom", "description": "ref" } } }, "name": "ButtonBase", "imports": [ diff --git a/packages/mui-base/src/Button/Button.tsx b/packages/mui-base/src/Button/Button.tsx index 6be0c51d98f9c3..fd12f5c90249c2 100644 --- a/packages/mui-base/src/Button/Button.tsx +++ b/packages/mui-base/src/Button/Button.tsx @@ -1,5 +1,6 @@ 'use client'; import * as React from 'react'; +import { refType } from '@mui/utils'; import PropTypes from 'prop-types'; import { PolymorphicComponent } from '../utils/PolymorphicComponent'; import { unstable_composeClasses as composeClasses } from '../composeClasses'; @@ -97,14 +98,7 @@ Button.propTypes /* remove-proptypes */ = { /** * A ref for imperative actions. It currently only supports `focusVisible()` action. */ - action: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.shape({ - current: PropTypes.shape({ - focusVisible: PropTypes.func.isRequired, - }), - }), - ]), + action: refType, /** * @ignore */ diff --git a/packages/mui-base/src/Input/Input.tsx b/packages/mui-base/src/Input/Input.tsx index 5614847edd287e..16534896ac7a00 100644 --- a/packages/mui-base/src/Input/Input.tsx +++ b/packages/mui-base/src/Input/Input.tsx @@ -1,5 +1,6 @@ 'use client'; import * as React from 'react'; +import { refType } from '@mui/utils'; import PropTypes from 'prop-types'; import { PolymorphicComponent } from '../utils/PolymorphicComponent'; import { isHostComponent } from '../utils/isHostComponent'; @@ -244,12 +245,7 @@ Input.propTypes /* remove-proptypes */ = { /** * @ignore */ - inputRef: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.shape({ - current: PropTypes.object, - }), - ]), + inputRef: refType, /** * Maximum number of rows to display when multiline option is set to true. */ diff --git a/packages/mui-base/src/Tab/Tab.tsx b/packages/mui-base/src/Tab/Tab.tsx index 5d728e4e9ef5c9..e3978d9dabc577 100644 --- a/packages/mui-base/src/Tab/Tab.tsx +++ b/packages/mui-base/src/Tab/Tab.tsx @@ -1,7 +1,7 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; -import { unstable_useForkRef as useForkRef } from '@mui/utils'; +import { unstable_useForkRef as useForkRef, refType } from '@mui/utils'; import { unstable_composeClasses as composeClasses } from '../composeClasses'; import { getTabUtilityClass } from './tabClasses'; import { TabProps, TabTypeMap, TabRootSlotProps, TabOwnerState } from './Tab.types'; @@ -87,14 +87,7 @@ Tab.propTypes /* remove-proptypes */ = { /** * A ref for imperative actions. It currently only supports `focusVisible()` action. */ - action: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.shape({ - current: PropTypes.shape({ - focusVisible: PropTypes.func.isRequired, - }), - }), - ]), + action: refType, /** * @ignore */ diff --git a/packages/mui-joy/src/Button/Button.tsx b/packages/mui-joy/src/Button/Button.tsx index 89d5067fdb3d2a..31ffe63ab9442a 100644 --- a/packages/mui-joy/src/Button/Button.tsx +++ b/packages/mui-joy/src/Button/Button.tsx @@ -4,7 +4,11 @@ import PropTypes from 'prop-types'; import { useButton } from '@mui/base/useButton'; import { unstable_composeClasses as composeClasses } from '@mui/base/composeClasses'; import { Interpolation } from '@mui/system'; -import { unstable_capitalize as capitalize, unstable_useForkRef as useForkRef } from '@mui/utils'; +import { + unstable_capitalize as capitalize, + unstable_useForkRef as useForkRef, + refType, +} from '@mui/utils'; import { styled, Theme, useThemeProps } from '../styles'; import { useColorInversion } from '../styles/ColorInversion'; import useSlot from '../utils/useSlot'; @@ -325,14 +329,7 @@ Button.propTypes /* remove-proptypes */ = { /** * A ref for imperative actions. It currently only supports `focusVisible()` action. */ - action: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.shape({ - current: PropTypes.shape({ - focusVisible: PropTypes.func.isRequired, - }), - }), - ]), + action: refType, /** * @ignore */ diff --git a/packages/mui-joy/src/IconButton/IconButton.tsx b/packages/mui-joy/src/IconButton/IconButton.tsx index 8a169ab2d456c1..bc84ac3b9ad6f5 100644 --- a/packages/mui-joy/src/IconButton/IconButton.tsx +++ b/packages/mui-joy/src/IconButton/IconButton.tsx @@ -1,7 +1,11 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; -import { unstable_capitalize as capitalize, unstable_useForkRef as useForkRef } from '@mui/utils'; +import { + unstable_capitalize as capitalize, + unstable_useForkRef as useForkRef, + refType, +} from '@mui/utils'; import { useButton } from '@mui/base/useButton'; import { unstable_composeClasses as composeClasses } from '@mui/base/composeClasses'; import { styled, useThemeProps } from '../styles'; @@ -201,14 +205,7 @@ IconButton.propTypes /* remove-proptypes */ = { /** * A ref for imperative actions. It currently only supports `focusVisible()` action. */ - action: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.shape({ - current: PropTypes.shape({ - focusVisible: PropTypes.func.isRequired, - }), - }), - ]), + action: refType, /** * @ignore */ diff --git a/packages/mui-joy/src/ListItemButton/ListItemButton.tsx b/packages/mui-joy/src/ListItemButton/ListItemButton.tsx index 0463696dac13a6..5cda7fe8e20770 100644 --- a/packages/mui-joy/src/ListItemButton/ListItemButton.tsx +++ b/packages/mui-joy/src/ListItemButton/ListItemButton.tsx @@ -2,7 +2,11 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; -import { unstable_capitalize as capitalize, unstable_useForkRef as useForkRef } from '@mui/utils'; +import { + unstable_capitalize as capitalize, + unstable_useForkRef as useForkRef, + refType, +} from '@mui/utils'; import { unstable_composeClasses as composeClasses } from '@mui/base/composeClasses'; import { useButton } from '@mui/base/useButton'; import { styled, useThemeProps } from '../styles'; @@ -213,14 +217,7 @@ ListItemButton.propTypes /* remove-proptypes */ = { /** * A ref for imperative actions. It currently only supports `focusVisible()` action. */ - action: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.shape({ - current: PropTypes.shape({ - focusVisible: PropTypes.func.isRequired, - }), - }), - ]), + action: refType, /** * If `true`, the list item is focused during the first mount. * Focus will also be triggered if the value changes from false to true. diff --git a/packages/mui-joy/src/Select/Select.tsx b/packages/mui-joy/src/Select/Select.tsx index 2b3f19a198941f..4389a017dbf3a8 100644 --- a/packages/mui-joy/src/Select/Select.tsx +++ b/packages/mui-joy/src/Select/Select.tsx @@ -3,7 +3,11 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; import { OverrideProps, DefaultComponentProps } from '@mui/types'; -import { unstable_capitalize as capitalize, unstable_useForkRef as useForkRef } from '@mui/utils'; +import { + unstable_capitalize as capitalize, + unstable_useForkRef as useForkRef, + refType, +} from '@mui/utils'; import { Popper, PopperProps } from '@mui/base/Popper'; import { useSelect, SelectProvider } from '@mui/base/useSelect'; import { SelectOption } from '@mui/base/useOption'; @@ -625,14 +629,7 @@ Select.propTypes /* remove-proptypes */ = { /** * A ref for imperative actions. It currently only supports `focusVisible()` action. */ - action: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.shape({ - current: PropTypes.shape({ - focusVisible: PropTypes.func.isRequired, - }), - }), - ]), + action: refType, /** * If `true`, the select element is focused during the first mount * @default false diff --git a/packages/mui-joy/src/Tab/Tab.tsx b/packages/mui-joy/src/Tab/Tab.tsx index c9d8342d03b361..e369fabf05ab31 100644 --- a/packages/mui-joy/src/Tab/Tab.tsx +++ b/packages/mui-joy/src/Tab/Tab.tsx @@ -2,7 +2,11 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { OverridableComponent } from '@mui/types'; -import { unstable_capitalize as capitalize, unstable_useForkRef as useForkRef } from '@mui/utils'; +import { + unstable_capitalize as capitalize, + unstable_useForkRef as useForkRef, + refType, +} from '@mui/utils'; import { unstable_composeClasses as composeClasses } from '@mui/base'; import { useTab } from '@mui/base/useTab'; import { StyledListItemButton } from '../ListItemButton/ListItemButton'; @@ -215,14 +219,7 @@ Tab.propTypes /* remove-proptypes */ = { /** * A ref for imperative actions. It currently only supports `focusVisible()` action. */ - action: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.shape({ - current: PropTypes.shape({ - focusVisible: PropTypes.func.isRequired, - }), - }), - ]), + action: refType, /** * @ignore */ diff --git a/packages/mui-material-next/src/ButtonBase/ButtonBase.tsx b/packages/mui-material-next/src/ButtonBase/ButtonBase.tsx index de46813447ad93..1f0913e15c9c53 100644 --- a/packages/mui-material-next/src/ButtonBase/ButtonBase.tsx +++ b/packages/mui-material-next/src/ButtonBase/ButtonBase.tsx @@ -299,15 +299,7 @@ ButtonBase.propTypes /* remove-proptypes */ = { /** * A ref that points to the `TouchRipple` element. */ - touchRippleRef: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.shape({ - current: PropTypes.shape({ - start: PropTypes.func.isRequired, - stop: PropTypes.func.isRequired, - }), - }), - ]), + touchRippleRef: refType, /** * Type attribute applied to the root component. * @default 'button' diff --git a/packages/mui-material/src/ButtonBase/ButtonBase.js b/packages/mui-material/src/ButtonBase/ButtonBase.js index 49366647405411..e3124655f2a1fe 100644 --- a/packages/mui-material/src/ButtonBase/ButtonBase.js +++ b/packages/mui-material/src/ButtonBase/ButtonBase.js @@ -521,16 +521,7 @@ ButtonBase.propTypes /* remove-proptypes */ = { /** * A ref that points to the `TouchRipple` element. */ - touchRippleRef: PropTypes.oneOfType([ - PropTypes.func, - PropTypes.shape({ - current: PropTypes.shape({ - pulsate: PropTypes.func.isRequired, - start: PropTypes.func.isRequired, - stop: PropTypes.func.isRequired, - }), - }), - ]), + touchRippleRef: refType, /** * @ignore */ diff --git a/packages/typescript-to-proptypes/src/createType.ts b/packages/typescript-to-proptypes/src/createType.ts index 4ca05ed12f4549..cdb36e84731d42 100644 --- a/packages/typescript-to-proptypes/src/createType.ts +++ b/packages/typescript-to-proptypes/src/createType.ts @@ -15,6 +15,7 @@ import { StringType, ObjectType, NumericType, + ReactRefType, } from './models'; export function createAnyType(init: { jsDoc: string | undefined }): AnyType { @@ -64,6 +65,13 @@ export function createElementType(init: { }; } +export function createReactRefType(init: { jsDoc: string | undefined }): ReactRefType { + return { + type: 'ReactRefNode', + jsDoc: init.jsDoc, + }; +} + export function createFunctionType(init: { jsDoc: string | undefined }): FunctionType { return { type: 'FunctionNode', diff --git a/packages/typescript-to-proptypes/src/generatePropTypes.ts b/packages/typescript-to-proptypes/src/generatePropTypes.ts index 004fbb17ab1416..3993562c907170 100644 --- a/packages/typescript-to-proptypes/src/generatePropTypes.ts +++ b/packages/typescript-to-proptypes/src/generatePropTypes.ts @@ -155,6 +155,10 @@ export function generatePropTypes( return `${importedName}.bool`; } + if (propType.type === 'ReactRefNode') { + return 'refType'; + } + if (propType.type === 'NumericNode') { return `${importedName}.number`; } diff --git a/packages/typescript-to-proptypes/src/getPropTypesFromFile.ts b/packages/typescript-to-proptypes/src/getPropTypesFromFile.ts index 0da13bc41aaac8..5623ed5631a6c1 100644 --- a/packages/typescript-to-proptypes/src/getPropTypesFromFile.ts +++ b/packages/typescript-to-proptypes/src/getPropTypesFromFile.ts @@ -19,6 +19,7 @@ import { createNumericType, createObjectType, createStringType, + createReactRefType, } from './createType'; import { PropTypeDefinition, PropTypesComponent, PropType } from './models'; @@ -291,6 +292,23 @@ function checkSymbol({ ts.isTypeReferenceNode(declaration.type) ) { const name = declaration.type.typeName.getText(); + + if (name === 'React.Ref') { + return { + $$id: project.createPropTypeId(symbol), + name: symbol.getName(), + jsDoc, + filenames: symbolFilenames, + propType: createUnionType({ + jsDoc, + types: [ + createUndefinedType({ jsDoc: undefined }), + createReactRefType({ jsDoc: undefined }), + ], + }), + }; + } + if ( name === 'React.ElementType' || name === 'React.JSXElementConstructor' || diff --git a/packages/typescript-to-proptypes/src/injectPropTypesInFile.ts b/packages/typescript-to-proptypes/src/injectPropTypesInFile.ts index 33be76a163c5ad..b8dfba90b8a09f 100644 --- a/packages/typescript-to-proptypes/src/injectPropTypesInFile.ts +++ b/packages/typescript-to-proptypes/src/injectPropTypesInFile.ts @@ -170,9 +170,11 @@ function createBabelPlugin({ return includeUnusedProps ? true : data.usedProps.includes(data.prop.name); }; - let importName = ''; - let needImport = false; - let alreadyImported = false; + let importNodeFromMuiUtils: babel.NodePath | null = null; + let hasRefTypeImportFromMuiUtils = false; + let needRefTypeImportFromMuiUtils = false; + let alreadyImportedPropTypesName: string | null = null; + let needImportFromPropTypePackage = false; let originalPropTypesPath: null | babel.NodePath = null; const previousPropTypesSource = new Map(); @@ -186,7 +188,7 @@ function createBabelPlugin({ const source = generatePropTypes(props, { ...otherOptions, - importedName: importName, + importedName: alreadyImportedPropTypesName ?? 'PropTypes', previousPropTypesSource, reconcilePropTypes, shouldInclude: (prop) => shouldInclude({ component: props, prop, usedProps }), @@ -194,7 +196,13 @@ function createBabelPlugin({ const emptyPropTypes = source === ''; if (!emptyPropTypes) { - needImport = true; + needImportFromPropTypePackage = true; + } + + // TODO: If we filter the injected proptypes in this file instead of in generatePropTypes. + // Then we could check correctly if some prop-type is a ref and not just rely on some string analysis. + if (source.includes(': refType')) { + needRefTypeImportFromMuiUtils = true; } const placeholder = `const a${uuid().replace(/-/g, '_')} = null;`; @@ -233,25 +241,23 @@ function createBabelPlugin({ visitor: { Program: { enter(path, state: any) { - if ( - !path.node.body.some((n) => { - if ( - babelTypes.isImportDeclaration(n) && - n.source.value === 'prop-types' && - n.specifiers.length - ) { - importName = n.specifiers[0].local.name; - alreadyImported = true; - return true; - } - return false; - }) - ) { - importName = 'PropTypes'; - } - path.get('body').forEach((nodePath) => { const { node } = nodePath; + + if (babelTypes.isImportDeclaration(node) && node.specifiers.length) { + if (node.source.value === 'prop-types') { + alreadyImportedPropTypesName = node.specifiers[0].local.name; + } else if (node.source.value === '@mui/utils') { + importNodeFromMuiUtils = nodePath; + const specifier = node.specifiers.find( + (el) => babelTypes.isImportSpecifier(el) && el.local.name === 'refType', + ); + if (specifier) { + hasRefTypeImportFromMuiUtils = true; + } + } + } + if ( babelTypes.isExpressionStatement(node) && babelTypes.isAssignmentExpression(node.expression, { operator: '=' }) && @@ -293,23 +299,54 @@ function createBabelPlugin({ }); }, exit(path) { - if (alreadyImported || !needImport) { - return; + if (alreadyImportedPropTypesName == null && needImportFromPropTypePackage) { + const propTypesImport = babel.template.ast( + `import PropTypes from 'prop-types'`, + ) as babel.types.ImportDeclaration; + + const firstImport = path + .get('body') + .find((nodePath) => babelTypes.isImportDeclaration(nodePath.node)); + + // Insert import after the first one to avoid issues with comment flags + if (firstImport) { + firstImport.insertAfter(propTypesImport); + } else { + path.node.body = [propTypesImport, ...path.node.body]; + } } - const propTypesImport = babel.template.ast( - `import ${importName} from 'prop-types'`, - ) as babel.types.ImportDeclaration; - - const firstImport = path - .get('body') - .find((nodePath) => babelTypes.isImportDeclaration(nodePath.node)); - - // Insert import after the first one to avoid issues with comment flags - if (firstImport) { - firstImport.insertAfter(propTypesImport); - } else { - path.node.body = [propTypesImport, ...path.node.body]; + if (needRefTypeImportFromMuiUtils && !hasRefTypeImportFromMuiUtils) { + if (importNodeFromMuiUtils) { + const node = importNodeFromMuiUtils.node as babel.types.ImportDeclaration; + importNodeFromMuiUtils.replaceWith( + babelTypes.importDeclaration( + [ + ...node.specifiers, + babelTypes.importSpecifier( + babelTypes.identifier('refType'), + babelTypes.identifier('refType'), + ), + ], + babelTypes.stringLiteral('@mui/utils'), + ), + ); + } else { + const refTypeImport = babel.template.ast( + `import { refType } from '@mui/utils'`, + ) as babel.types.ImportDeclaration; + + const firstImport = path + .get('body') + .find((nodePath) => babelTypes.isImportDeclaration(nodePath.node)); + + // Insert import after the first one to avoid issues with comment flags + if (firstImport) { + firstImport.insertAfter(refTypeImport); + } else { + path.node.body = [refTypeImport, ...path.node.body]; + } + } } }, }, diff --git a/packages/typescript-to-proptypes/src/models.ts b/packages/typescript-to-proptypes/src/models.ts index 626461883336f1..df7b36c1ce649f 100644 --- a/packages/typescript-to-proptypes/src/models.ts +++ b/packages/typescript-to-proptypes/src/models.ts @@ -21,6 +21,7 @@ export type PropType = | BooleanType | DOMElementType | ElementType + | ReactRefType | FunctionType | InstanceOfType | InterfaceType @@ -63,6 +64,10 @@ export interface ElementType extends BasePropType { type: 'ElementNode'; } +export interface ReactRefType extends BasePropType { + type: 'ReactRefNode'; +} + export interface FunctionType extends BasePropType { type: 'FunctionNode'; } diff --git a/scripts/generateProptypes.ts b/scripts/generateProptypes.ts index 09b923a9b33b79..e4bf0ed659c4e6 100644 --- a/scripts/generateProptypes.ts +++ b/scripts/generateProptypes.ts @@ -248,7 +248,10 @@ async function generateProptypes( ensureBabelPluginTransformReactRemovePropTypesIntegration: true, getSortLiteralUnions, reconcilePropTypes: (prop, previous, generated) => { - const usedCustomValidator = previous !== undefined && !previous.startsWith('PropTypes'); + const usedCustomValidator = + previous !== undefined && + !previous.startsWith('PropTypes') && + !previous.startsWith('refType'); const ignoreGenerated = previous !== undefined && previous.startsWith('PropTypes /* @typescript-to-proptypes-ignore */');