]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-21017 TypeScript: the `children` prop must now be explicit (see https://react...
authorDavid Cho-Lerat <david.cho-lerat@sonarsource.com>
Tue, 21 Nov 2023 08:28:45 +0000 (09:28 +0100)
committersonartech <sonartech@sonarsource.com>
Fri, 24 Nov 2023 20:02:44 +0000 (20:02 +0000)
57 files changed:
server/sonar-web/design-system/src/components/FacetBox.tsx
server/sonar-web/design-system/src/components/FavoriteButton.tsx
server/sonar-web/design-system/src/components/InteractiveIcon.tsx
server/sonar-web/design-system/src/components/Tags.tsx
server/sonar-web/design-system/src/components/Tooltip.tsx
server/sonar-web/design-system/src/components/avatar/GenericAvatar.tsx
server/sonar-web/design-system/src/components/buttons/ButtonPrimary.tsx
server/sonar-web/design-system/src/components/buttons/ButtonSecondary.tsx
server/sonar-web/design-system/src/components/buttons/DangerButtonPrimary.tsx
server/sonar-web/design-system/src/components/buttons/DangerButtonSecondary.tsx
server/sonar-web/design-system/src/components/buttons/ThirdPartyButton.tsx
server/sonar-web/design-system/src/components/buttons/WrapperButton.tsx
server/sonar-web/design-system/src/components/clipboard.tsx
server/sonar-web/design-system/src/components/icons/Icon.tsx
server/sonar-web/design-system/src/theme/withTheme.tsx
server/sonar-web/design-system/src/types/misc.ts
server/sonar-web/src/main/js/app/components/PageTracker.tsx
server/sonar-web/src/main/js/app/components/StartupModal.tsx
server/sonar-web/src/main/js/app/components/admin/withAdminPagesOutletContext.tsx
server/sonar-web/src/main/js/app/components/app-state/withAppStateContext.tsx
server/sonar-web/src/main/js/app/components/available-features/withAvailableFeatures.tsx
server/sonar-web/src/main/js/app/components/componentContext/withComponentContext.tsx
server/sonar-web/src/main/js/app/components/current-user/CurrentUserContextProvider.tsx
server/sonar-web/src/main/js/app/components/current-user/withCurrentUserContext.tsx
server/sonar-web/src/main/js/app/components/languages/LanguagesContextProvider.tsx
server/sonar-web/src/main/js/app/components/languages/withLanguagesContext.tsx
server/sonar-web/src/main/js/app/components/metrics/MetricsContextProvider.tsx
server/sonar-web/src/main/js/app/components/metrics/withMetricsContext.tsx
server/sonar-web/src/main/js/apps/quality-profiles/qualityProfilesContext.tsx
server/sonar-web/src/main/js/apps/settings/components/inputs/Input.tsx
server/sonar-web/src/main/js/apps/settings/components/inputs/InputForSecured.tsx
server/sonar-web/src/main/js/apps/settings/components/inputs/PrimitiveInput.tsx
server/sonar-web/src/main/js/components/a11y/A11yProvider.tsx
server/sonar-web/src/main/js/components/controls/Radio.tsx
server/sonar-web/src/main/js/components/controls/Tooltip.tsx
server/sonar-web/src/main/js/components/embed-docs-modal/SuggestionsProvider.tsx
server/sonar-web/src/main/js/components/hoc/utils.ts
server/sonar-web/src/main/js/components/hoc/whenLoggedIn.tsx
server/sonar-web/src/main/js/components/hoc/withCLanguageFeature.tsx
server/sonar-web/src/main/js/components/hoc/withIndexationContext.tsx
server/sonar-web/src/main/js/components/hoc/withIndexationGuard.tsx
server/sonar-web/src/main/js/components/hoc/withKeyboardNavigation.tsx
server/sonar-web/src/main/js/components/hoc/withLocation.tsx
server/sonar-web/src/main/js/components/hoc/withNotifications.tsx
server/sonar-web/src/main/js/components/hoc/withRouter.tsx
server/sonar-web/src/main/js/components/hoc/withScrollTo.tsx
server/sonar-web/src/main/js/components/icons/ProjectLinkIcon.tsx
server/sonar-web/src/main/js/components/permissions/HoldersList.tsx
server/sonar-web/src/main/js/components/rules/MoreInfoRuleDescription.tsx
server/sonar-web/src/main/js/components/tutorials/jenkins/JenkinsStep.tsx
server/sonar-web/src/main/js/components/ui/popups.tsx
server/sonar-web/src/main/js/components/workspace/Workspace.tsx
server/sonar-web/src/main/js/components/workspace/WorkspaceHeader.tsx
server/sonar-web/src/main/js/components/workspace/WorkspacePortal.tsx
server/sonar-web/src/main/js/helpers/testUtils.ts
server/sonar-web/src/main/js/queries/branch.tsx
server/sonar-web/src/main/js/types/misc.ts

index 302799edf9dd30913776952800b94858296a01b6..08a6e4ec2c198319cac7b26d531f238973828143 100644 (file)
@@ -51,7 +51,7 @@ export interface FacetBoxProps {
   onClear?: () => void;
   onClick?: (isOpen: boolean) => void;
   open?: boolean;
-  tooltipComponent?: React.ComponentType<{ overlay: React.ReactNode }>;
+  tooltipComponent?: React.ComponentType<React.PropsWithChildren<{ overlay: React.ReactNode }>>;
 }
 
 export function FacetBox(props: FacetBoxProps) {
index 10c8f717c04cb242d06d3124d2b8e08db935579f..9b822c087e5e766a3d864c8a0a70fef3e0967351 100644 (file)
@@ -28,7 +28,7 @@ interface Props {
   innerRef?: React.Ref<HTMLButtonElement>;
   overlay: string;
   toggleFavorite: VoidFunction;
-  tooltip?: React.ComponentType<{ overlay: React.ReactNode }>;
+  tooltip?: React.ComponentType<React.PropsWithChildren<{ overlay: React.ReactNode }>>;
 }
 
 export function FavoriteButton(props: Props) {
index 00fee47419220f1512cc54b328c483a33a112f2c..f00a59a6f64d47991999b8a0a3b309e193d25d5a 100644 (file)
@@ -33,7 +33,7 @@ import { IconProps } from './icons/Icon';
 export type InteractiveIconSize = 'small' | 'medium';
 
 export interface InteractiveIconProps {
-  Icon: React.ComponentType<IconProps>;
+  Icon: React.ComponentType<React.PropsWithChildren<IconProps>>;
   'aria-label': string;
   children?: React.ReactNode;
   className?: string;
@@ -147,7 +147,9 @@ const IconButton = styled.button`
   ${buttonIconStyle}
 `;
 
-export const InteractiveIcon: React.FC<InteractiveIconProps> = styled(InteractiveIconBase)`
+export const InteractiveIcon: React.FC<React.PropsWithChildren<InteractiveIconProps>> = styled(
+  InteractiveIconBase,
+)`
   --background: ${themeColor('interactiveIcon')};
   --backgroundHover: ${themeColor('interactiveIconHover')};
   --color: ${({ currentColor, theme }) =>
@@ -156,11 +158,15 @@ export const InteractiveIcon: React.FC<InteractiveIconProps> = styled(Interactiv
   --focus: ${themeColor('interactiveIconFocus', OPACITY_20_PERCENT)};
 `;
 
-export const DiscreetInteractiveIcon: React.FC<InteractiveIconProps> = styled(InteractiveIcon)`
+export const DiscreetInteractiveIcon: React.FC<
+  React.PropsWithChildren<InteractiveIconProps>
+> = styled(InteractiveIcon)`
   --color: ${themeColor('discreetInteractiveIcon')};
 `;
 
-export const DestructiveIcon: React.FC<InteractiveIconProps> = styled(InteractiveIconBase)`
+export const DestructiveIcon: React.FC<React.PropsWithChildren<InteractiveIconProps>> = styled(
+  InteractiveIconBase,
+)`
   --background: ${themeColor('destructiveIcon')};
   --backgroundHover: ${themeColor('destructiveIconHover')};
   --color: ${themeContrast('destructiveIcon')};
@@ -168,7 +174,9 @@ export const DestructiveIcon: React.FC<InteractiveIconProps> = styled(Interactiv
   --focus: ${themeColor('destructiveIconFocus', OPACITY_20_PERCENT)};
 `;
 
-export const DismissProductNewsIcon: React.FC<InteractiveIconProps> = styled(InteractiveIcon)`
+export const DismissProductNewsIcon: React.FC<
+  React.PropsWithChildren<InteractiveIconProps>
+> = styled(InteractiveIcon)`
   --background: ${themeColor('productNews')};
   --backgroundHover: ${themeColor('productNewsHover')};
   --color: ${themeContrast('productNews')};
index 88c613bc9a93eb8e73842662094584844fe3698a..200415cfb65edee29877ef2a09a726ac1f18f947 100644 (file)
@@ -39,7 +39,7 @@ interface Props {
   popupPlacement?: PopupPlacement;
   tags: string[];
   tagsToDisplay?: number;
-  tooltip?: React.ComponentType<{ overlay: React.ReactNode }>;
+  tooltip?: React.ComponentType<React.PropsWithChildren<{ overlay: React.ReactNode }>>;
 }
 
 export function Tags({
index 209a8fdddd2346683627670eac76ae2cab5f993b..1b5a763dec2890b22dc9af7db33eda457862aaba 100644 (file)
@@ -401,7 +401,7 @@ export class TooltipInner extends React.Component<TooltipProps, State> {
   }
 }
 
-class TooltipPortal extends React.Component {
+class TooltipPortal extends React.Component<React.PropsWithChildren> {
   el: HTMLElement;
 
   constructor(props: object) {
index 2590ccbefdbb347975c5e2349605d7e0982031ee..2125141e3679ef54b806061cd1b03b086cf2435a 100644 (file)
@@ -26,7 +26,7 @@ import { IconProps } from '../icons/Icon';
 import { Size, iconSizeMap, sizeMap } from './utils';
 
 export interface GenericAvatarProps {
-  Icon?: React.ComponentType<IconProps>;
+  Icon?: React.ComponentType<React.PropsWithChildren<IconProps>>;
   className?: string;
   name: string;
   size?: Size;
index 6550e5c65884762c6592e140cc9c292963a691e1..0b3365667a744eeba0b97b5b1b8e14b72120de66 100644 (file)
@@ -32,6 +32,6 @@ export const PrimaryStyle = (props: ThemedProps) => css`
   --border: ${themeBorder('default', 'transparent')(props)};
 `;
 
-export const ButtonPrimary: React.FC<ButtonProps> = styled(Button)`
+export const ButtonPrimary: React.FC<React.PropsWithChildren<ButtonProps>> = styled(Button)`
   ${PrimaryStyle}
 `;
index 8769d3f4052cb95768c33f84ba4a474f759ab1bc..09ad0b73bfe5e9bf7afa3ec909aa7cf9748f22fb 100644 (file)
@@ -21,7 +21,7 @@ import styled from '@emotion/styled';
 import { OPACITY_20_PERCENT, themeBorder, themeColor, themeContrast } from '../../helpers';
 import { Button, ButtonProps } from './Button';
 
-export const ButtonSecondary: React.FC<ButtonProps> = styled(Button)`
+export const ButtonSecondary: React.FC<React.PropsWithChildren<ButtonProps>> = styled(Button)`
   --background: ${themeColor('buttonSecondary')};
   --backgroundHover: ${themeColor('buttonSecondaryHover')};
   --color: ${themeContrast('buttonSecondary')};
index d954a539dfae22d618940258923019c43455182e..6fc7d558977c1f471e5fcd8cc20d8dfcf3d8811b 100644 (file)
@@ -22,7 +22,7 @@ import styled from '@emotion/styled';
 import { OPACITY_20_PERCENT, themeBorder, themeColor, themeContrast } from '../../helpers';
 import { Button, ButtonProps } from './Button';
 
-export const DangerButtonPrimary: React.FC<ButtonProps> = styled(Button)`
+export const DangerButtonPrimary: React.FC<React.PropsWithChildren<ButtonProps>> = styled(Button)`
   --background: ${themeColor('dangerButton')};
   --backgroundHover: ${themeColor('dangerButtonHover')};
   --color: ${themeContrast('dangerButton')};
index 0decc1751b3c05676d51277cd865b8ee18f6749c..02768ad8de8b45098f430220819aa38e41159386 100644 (file)
@@ -22,7 +22,7 @@ import styled from '@emotion/styled';
 import { OPACITY_20_PERCENT, themeBorder, themeColor, themeContrast } from '../../helpers';
 import { Button, ButtonProps } from './Button';
 
-export const DangerButtonSecondary: React.FC<ButtonProps> = styled(Button)`
+export const DangerButtonSecondary: React.FC<React.PropsWithChildren<ButtonProps>> = styled(Button)`
   --background: ${themeColor('dangerButtonSecondary')};
   --backgroundHover: ${themeColor('dangerButtonSecondaryHover')};
   --color: ${themeContrast('dangerButtonSecondary')};
index 86a9e0b54acc861ac65f367b669eaa0ebfa81f91..9f958e79f45e1d96142ffebadbfd410b3c3ddb51 100644 (file)
@@ -39,7 +39,7 @@ export function ThirdPartyButton({ children, iconPath, name, ...buttonProps }: T
   );
 }
 
-const ThirdPartyButtonStyled: React.FC<ButtonProps> = styled(Button)`
+const ThirdPartyButtonStyled: React.FC<React.PropsWithChildren<ButtonProps>> = styled(Button)`
   --background: ${themeColor('thirdPartyButton')};
   --backgroundHover: ${themeColor('thirdPartyButtonHover')};
   --color: ${themeContrast('thirdPartyButton')};
index 64d86fc613f95c539f761a03aaafdf5942df64f3..9097c6efe886d9e8bd043c7af3b8f56f273bb028 100644 (file)
@@ -22,7 +22,7 @@ import styled from '@emotion/styled';
 import { OPACITY_20_PERCENT, themeColor } from '../../helpers';
 import { Button, ButtonProps } from './Button';
 
-export const WrapperButton: React.FC<ButtonProps> = styled(Button)`
+export const WrapperButton: React.FC<React.PropsWithChildren<ButtonProps>> = styled(Button)`
   --background: none;
   --backgroundHover: none;
   --color: none;
index 460a8bf803e01005802293ec8770f5ee671a7351..0bb5155d74267afe90a888f3024c461a2f2ba125 100644 (file)
@@ -133,7 +133,7 @@ export function ClipboardButton({
 }
 
 interface IconButtonProps {
-  Icon?: React.ComponentType<IconProps>;
+  Icon?: React.ComponentType<React.PropsWithChildren<IconProps>>;
   'aria-label'?: string;
   className?: string;
   copiedLabel?: string;
index 58b03f1aa65fc29636645a979f3fad4e258e75ac..5acfd4ee05c7dbcde5c567a5cafb3e40ad879664 100644 (file)
@@ -87,9 +87,9 @@ export function CustomIcon(props: Props) {
 }
 
 export function OcticonHoc(
-  WrappedOcticon: React.ComponentType<OcticonProps>,
-  displayName?: string
-): React.ComponentType<IconProps> {
+  WrappedOcticon: React.ComponentType<React.PropsWithChildren<OcticonProps>>,
+  displayName?: string,
+): React.ComponentType<React.PropsWithChildren<IconProps>> {
   function IconWrapper({ fill, ...props }: IconProps) {
     const theme = useTheme();
 
index 64e657fc57ebb59b1dd350626d572748e4de950b..07713660df109e61fa3aafd1065e2d810729ed77 100644 (file)
@@ -26,8 +26,8 @@ export interface ThemeProp {
 }
 
 export function withTheme<P>(
-  WrappedComponent: React.ComponentType<P & ThemeProp>
-): React.ComponentType<P> {
+  WrappedComponent: React.ComponentType<React.PropsWithChildren<P & ThemeProp>>,
+): React.ComponentType<React.PropsWithChildren<P>> {
   return function WrappedComponentWithTheme(props: P) {
     const theme = useTheme();
 
index ea95b30ffc6148381386d8aaf5b0a3c88bba38f3..84faf6ffa497ce19664c0af39fc803d095c15b06 100644 (file)
@@ -18,4 +18,5 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-export type FCProps<T extends React.FunctionComponent<any>> = Parameters<T>[0];
+export type FCProps<T extends React.FunctionComponent<React.PropsWithChildren<any>>> =
+  Parameters<T>[0];
index 0bbd94b90ff7df4d73e7c0c5d4c7e593919513ff..d99bc293d94f5fe5709435f2d4339b4b3286d445 100644 (file)
@@ -35,7 +35,7 @@ interface State {
   lastLocation?: string;
 }
 
-export class PageTracker extends React.Component<Props, State> {
+export class PageTracker extends React.Component<React.PropsWithChildren<Props>, State> {
   state: State = {};
 
   componentDidMount() {
index 80b283d2331c3ed720dd8809b520f4b2abfc9c18..6acaa6e8bbef4f986537065040d7337e6c238b10 100644 (file)
@@ -41,7 +41,7 @@ interface State {
 
 const LICENSE_PROMPT = 'sonarqube.license.prompt';
 
-export class StartupModal extends React.PureComponent<Props, State> {
+export class StartupModal extends React.PureComponent<React.PropsWithChildren<Props>, State> {
   state: State = {};
 
   componentDidMount() {
index b241258efb5d036c290adcdf3fad5e9eb63bde77..b5d3da6ff84743cd5aea9345b66e55524f47998b 100644 (file)
@@ -22,7 +22,9 @@ import { useOutletContext } from 'react-router-dom';
 import { AdminPagesContext } from '../../../types/admin';
 
 export default function withAdminPagesOutletContext(
-  WrappedComponent: React.ComponentType<AdminPagesContext>,
+  WrappedComponent: React.ComponentType<
+    React.PropsWithChildren<React.PropsWithChildren<AdminPagesContext>>
+  >,
 ) {
   return function WithAdminPagesOutletContext() {
     const { adminPages } = useOutletContext<AdminPagesContext>();
index 1dc86de5a8c0926b5b7dcac015683d6fa684d397..5a0b13d06af679858c0a46af581407a7ccd897bb 100644 (file)
@@ -27,7 +27,9 @@ export interface WithAppStateContextProps {
 }
 
 export default function withAppStateContext<P>(
-  WrappedComponent: React.ComponentType<P & WithAppStateContextProps>,
+  WrappedComponent: React.ComponentType<
+    React.PropsWithChildren<React.PropsWithChildren<P & WithAppStateContextProps>>
+  >,
 ) {
   return class WithAppStateContext extends React.PureComponent<
     Omit<P, keyof WithAppStateContextProps>
index d81dc252fd030e073164ffff3175665e8bce14d3..bc6fdc071739b3ab5d72635f0296734b7837285a 100644 (file)
@@ -27,7 +27,9 @@ export interface WithAvailableFeaturesProps {
 }
 
 export default function withAvailableFeatures<P>(
-  WrappedComponent: React.ComponentType<P & WithAvailableFeaturesProps>,
+  WrappedComponent: React.ComponentType<
+    React.PropsWithChildren<React.PropsWithChildren<P & WithAvailableFeaturesProps>>
+  >,
 ) {
   return class WithAvailableFeatures extends React.PureComponent<
     Omit<P, keyof WithAvailableFeaturesProps>
index 8d5049869d9a1b9922eb6b7f2310e2e8bf3f30ed..122706e9f6304ca779c682b58bfc558cb06c82e9 100644 (file)
@@ -23,7 +23,7 @@ import { ComponentContextShape } from '../../../types/component';
 import { ComponentContext } from './ComponentContext';
 
 export default function withComponentContext<P extends Partial<ComponentContextShape>>(
-  WrappedComponent: React.ComponentType<P>,
+  WrappedComponent: React.ComponentType<React.PropsWithChildren<React.PropsWithChildren<P>>>,
 ) {
   return class WithComponentContext extends React.PureComponent<
     Omit<P, keyof ComponentContextShape>
index 7408d4fdd363a4229d3830962fc6d9828d4df70b..b726c161d25cc94d71efada0ab57b4bfb7009e44 100644 (file)
@@ -29,7 +29,10 @@ interface State {
   currentUser: CurrentUser;
 }
 
-export default class CurrentUserContextProvider extends React.PureComponent<Props, State> {
+export default class CurrentUserContextProvider extends React.PureComponent<
+  React.PropsWithChildren<Props>,
+  State
+> {
   constructor(props: Props) {
     super(props);
     this.state = { currentUser: props.currentUser ?? { isLoggedIn: false, dismissedNotices: {} } };
index c3695f1f88ec598662af980138d1acbaad0bf479..e3cebd7f13ab020304e82390e36283901436c9b1 100644 (file)
@@ -22,7 +22,11 @@ import { getWrappedDisplayName } from '../../../components/hoc/utils';
 import { CurrentUserContext, CurrentUserContextInterface } from './CurrentUserContext';
 
 export default function withCurrentUserContext<P>(
-  WrappedComponent: React.ComponentType<P & Pick<CurrentUserContextInterface, 'currentUser'>>,
+  WrappedComponent: React.ComponentType<
+    React.PropsWithChildren<
+      React.PropsWithChildren<P & Pick<CurrentUserContextInterface, 'currentUser'>>
+    >
+  >,
 ) {
   return class WithCurrentUserContext extends React.PureComponent<
     Omit<P, 'currentUser' | 'updateCurrentUserHomepage' | 'updateDismissedNotices'>
index 9e5d6f5dc137f0fbdfea2b01c65f06b6d63a8c25..4275dac2309cb8fe6aba8a47816847a53e21d1ed 100644 (file)
@@ -27,7 +27,10 @@ interface State {
   languages: Languages;
 }
 
-export default class LanguagesContextProvider extends React.PureComponent<{}, State> {
+export default class LanguagesContextProvider extends React.PureComponent<
+  React.PropsWithChildren,
+  State
+> {
   mounted = false;
   state: State = {
     languages: {},
index f12107b3a52907b6d2d390cb3adf006b28797576..6b2324f4d249c6231846e311ee028f066da9b0ff 100644 (file)
@@ -27,7 +27,9 @@ export interface WithLanguagesContextProps {
 }
 
 export default function withLanguagesContext<P>(
-  WrappedComponent: React.ComponentType<P & WithLanguagesContextProps>,
+  WrappedComponent: React.ComponentType<
+    React.PropsWithChildren<React.PropsWithChildren<P & WithLanguagesContextProps>>
+  >,
 ) {
   return class WithLanguagesContext extends React.PureComponent<
     Omit<P, keyof WithLanguagesContextProps>
index 529328f7b50825ca045b4cfe6ff32ed4d63da1d3..8f64c67bfdafad168f121747bcd68b1a9f3afdf8 100644 (file)
@@ -27,7 +27,10 @@ interface State {
   metrics: Dict<Metric>;
 }
 
-export default class MetricsContextProvider extends React.PureComponent<{}, State> {
+export default class MetricsContextProvider extends React.PureComponent<
+  React.PropsWithChildren,
+  State
+> {
   mounted = false;
   state: State = {
     metrics: {},
index e17c3247762ab98add2be5c0d3574726a1396cdf..ac6caa0a9297d31f64eb26e6df3b2ebfdc805afe 100644 (file)
@@ -27,7 +27,9 @@ export interface WithMetricsContextProps {
 }
 
 export default function withMetricsContext<P>(
-  WrappedComponent: React.ComponentType<P & WithMetricsContextProps>,
+  WrappedComponent: React.ComponentType<
+    React.PropsWithChildren<React.PropsWithChildren<P & WithMetricsContextProps>>
+  >,
 ) {
   return class WithMetricsContext extends React.PureComponent<
     Omit<P, keyof WithMetricsContextProps>
index 3e17c24bc2b7f8909a44e35a9a9b0b4d9c148a98..30e6b39962decdc016373b6e3d4c9014e9939e4d 100644 (file)
@@ -34,17 +34,20 @@ export interface QualityProfilesContextProps {
 }
 
 export function withQualityProfilesContext<P extends Partial<QualityProfilesContextProps>>(
-  WrappedComponent: React.ComponentType<P>,
-): React.ComponentType<Omit<P, keyof QualityProfilesContextProps>> {
+  WrappedComponent: React.ComponentType<React.PropsWithChildren<React.PropsWithChildren<P>>>,
+): React.ComponentType<
+  React.PropsWithChildren<React.PropsWithChildren<Omit<P, keyof QualityProfilesContextProps>>>
+> {
   function ComponentWithQualityProfilesProps(props: P) {
     const context = useOutletContext<QualityProfilesContextProps>();
     return <WrappedComponent {...props} {...context} />;
   }
 
-  (ComponentWithQualityProfilesProps as React.FC<P>).displayName = getWrappedDisplayName(
-    WrappedComponent,
-    'withQualityProfilesContext',
-  );
+  (
+    ComponentWithQualityProfilesProps as React.FC<
+      React.PropsWithChildren<React.PropsWithChildren<P>>
+    >
+  ).displayName = getWrappedDisplayName(WrappedComponent, 'withQualityProfilesContext');
 
   return ComponentWithQualityProfilesProps;
 }
index 409f60e03241f38dd74babdace146c669e0f44c2..57001a7be6991cdfab54d68d43ebaee81492bc7e 100644 (file)
@@ -37,7 +37,9 @@ export default function Input(props: DefaultInputProps) {
   const { definition } = setting;
   const name = getUniqueName(definition);
 
-  let Input: React.ComponentType<DefaultSpecializedInputProps> = PrimitiveInput;
+  let Input: React.ComponentType<
+    React.PropsWithChildren<React.PropsWithChildren<DefaultSpecializedInputProps>>
+  > = PrimitiveInput;
 
   if (isCategoryDefinition(definition) && definition.multiValues) {
     Input = MultiValueInput;
index 558e0f93ba575fc56034317e1ae48fb1a851f760..2a7294408287927a9ae3fd6055ef79b1e54d0abb 100644 (file)
@@ -35,7 +35,9 @@ interface State {
 }
 
 interface Props extends DefaultInputProps {
-  input: React.ComponentType<DefaultSpecializedInputProps>;
+  input: React.ComponentType<
+    React.PropsWithChildren<React.PropsWithChildren<DefaultSpecializedInputProps>>
+  >;
 }
 
 export default class InputForSecured extends React.PureComponent<Props, State> {
index b2f09b43cc080ac7d212d19665d6b2abde17ce31..6c23cbafaeb8070905812d4a2760052b3ea80ac6 100644 (file)
@@ -29,7 +29,11 @@ import InputForSingleSelectList from './InputForSingleSelectList';
 import InputForString from './InputForString';
 import InputForText from './InputForText';
 
-function withOptions(options: string[]): React.ComponentType<DefaultSpecializedInputProps> {
+function withOptions(
+  options: string[],
+): React.ComponentType<
+  React.PropsWithChildren<React.PropsWithChildren<DefaultSpecializedInputProps>>
+> {
   return function Wrapped(props: DefaultSpecializedInputProps) {
     return <InputForSingleSelectList options={options} {...props} />;
   };
@@ -39,7 +43,9 @@ export default function PrimitiveInput(props: DefaultSpecializedInputProps) {
   const { setting, name, isDefault, ...other } = props;
   const { definition } = setting;
   const typeMapping: {
-    [type in SettingType]?: React.ComponentType<DefaultSpecializedInputProps>;
+    [type in SettingType]?: React.ComponentType<
+      React.PropsWithChildren<React.PropsWithChildren<DefaultSpecializedInputProps>>
+    >;
   } = {
     STRING: InputForString,
     TEXT: InputForText,
index 131edf13f462def0d3cc1d2f0bc8789a625f457d..77161816ba51ed992cd2b48ec18c35c2e693bef4 100644 (file)
@@ -26,7 +26,7 @@ interface State {
   links: A11ySkipLink[];
 }
 
-export default class A11yProvider extends React.Component<{}, State> {
+export default class A11yProvider extends React.Component<React.PropsWithChildren, State> {
   keys: string[] = [];
   state: State = { links: [] };
 
index 9c38e35d9cf1d86035bde75bec7e9d0ea8da794a..8a303c5bad81cdeb03ae10fa9083d87ebed7d539 100644 (file)
@@ -31,7 +31,7 @@ interface Props {
   ariaLabel?: string;
 }
 
-export default class Radio extends React.PureComponent<Props> {
+export default class Radio extends React.PureComponent<React.PropsWithChildren<Props>> {
   handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
     event.preventDefault();
 
index d84e567c793cc7cff15fd91830e2b50d2ca4b369..cf0171745deafd77d45d0be58b569269ac17a8f7 100644 (file)
@@ -452,7 +452,7 @@ export class TooltipInner extends React.Component<TooltipProps, State> {
   }
 }
 
-class TooltipPortal extends React.Component {
+class TooltipPortal extends React.Component<React.PropsWithChildren<{}>> {
   el: HTMLElement;
 
   constructor(props: {}) {
index f5347bd3901ffd2c5377dc9612ba051c5218565c..70b972aac12e14baab1622db3321bab306db0722 100644 (file)
@@ -28,7 +28,7 @@ interface State {
   suggestions: SuggestionLink[];
 }
 
-export default class SuggestionsProvider extends React.Component<{}, State> {
+export default class SuggestionsProvider extends React.Component<React.PropsWithChildren, State> {
   keys: string[] = [];
   state: State = { suggestions: [] };
 
index b36966d78bda2225389e74abe5a96460488ab9cd..de17d1bdf59a7f9a4b4d600625ae5303a7cd8f55 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 export function getWrappedDisplayName<P>(
-  WrappedComponent: React.ComponentType<P>,
+  WrappedComponent: React.ComponentType<React.PropsWithChildren<React.PropsWithChildren<P>>>,
   hocName: string,
 ) {
   const wrappedDisplayName = WrappedComponent.displayName ?? WrappedComponent.name ?? 'Component';
index a86c1c25e19c860196d500b8e149d00a84aa491c..682f3c22ce1fa9a136b1fd1ea3efa81205a48f31 100644 (file)
@@ -23,7 +23,9 @@ import handleRequiredAuthentication from '../../helpers/handleRequiredAuthentica
 import { CurrentUser, isLoggedIn } from '../../types/users';
 import { getWrappedDisplayName } from './utils';
 
-export function whenLoggedIn<P>(WrappedComponent: React.ComponentType<P>) {
+export function whenLoggedIn<P>(
+  WrappedComponent: React.ComponentType<React.PropsWithChildren<React.PropsWithChildren<P>>>,
+) {
   class Wrapper extends React.Component<P & { currentUser: CurrentUser }> {
     static displayName = getWrappedDisplayName(WrappedComponent, 'whenLoggedIn');
 
index df6fa13659cb548330c22268692fb6572d5f95b5..a7eb2b41b75951b0f04f9e01b523cce59504ee46 100644 (file)
@@ -22,7 +22,9 @@ import { LanguagesContext } from '../../app/components/languages/LanguagesContex
 import { getWrappedDisplayName } from './utils';
 
 export function withCLanguageFeature<P>(
-  WrappedComponent: React.ComponentType<P & { hasCLanguageFeature: boolean }>,
+  WrappedComponent: React.ComponentType<
+    React.PropsWithChildren<React.PropsWithChildren<P & { hasCLanguageFeature: boolean }>>
+  >,
 ) {
   class Wrapper extends React.Component<Omit<P, 'hasCLanguageFeature'>> {
     static displayName = getWrappedDisplayName(WrappedComponent, 'withCLanguageFeature');
index 9d9625c65ec7cd296c20a96f3fb230f0ae2115ad..a6e50ed6e0f7bb9815f319e40030627eafffcb54 100644 (file)
@@ -27,7 +27,9 @@ export interface WithIndexationContextProps {
 }
 
 export default function withIndexationContext<P>(
-  WrappedComponent: React.ComponentType<P & WithIndexationContextProps>,
+  WrappedComponent: React.ComponentType<
+    React.PropsWithChildren<React.PropsWithChildren<P & WithIndexationContextProps>>
+  >,
 ) {
   return class WithIndexationContext extends React.PureComponent<
     Omit<P, keyof WithIndexationContextProps>
index f3b882132d4ea2145325675e563d05c0d2d37c88..66efb6f5441addfcd63a48439add2c846ecc65ce 100644 (file)
@@ -25,7 +25,7 @@ export default function withIndexationGuard<P>({
   Component,
   showIndexationMessage,
 }: {
-  Component: React.ComponentType<P>;
+  Component: React.ComponentType<React.PropsWithChildren<React.PropsWithChildren<P>>>;
   showIndexationMessage: (props: P) => boolean;
 }) {
   return function WithIndexationGuard(props: React.PropsWithChildren<P>) {
index 0a1e1f0a3316cc60228fe09c222dc3d7c395c79e..ccf20bab442a6ced8ae4fba48415de58cada719a 100644 (file)
@@ -36,7 +36,9 @@ export interface WithKeyboardNavigationProps {
 }
 
 export default function withKeyboardNavigation<P>(
-  WrappedComponent: React.ComponentType<P & Partial<WithKeyboardNavigationProps>>,
+  WrappedComponent: React.ComponentType<
+    React.PropsWithChildren<React.PropsWithChildren<P & Partial<WithKeyboardNavigationProps>>>
+  >,
 ) {
   return class Wrapper extends React.Component<P & WithKeyboardNavigationProps> {
     static displayName = getWrappedDisplayName(WrappedComponent, 'withKeyboardNavigation');
index ea155eca671e3f9e697e88e6eed0acd11be99521..21713420d5219cefd43f2fcfb628f8a36395a1f4 100644 (file)
@@ -21,7 +21,9 @@ import * as React from 'react';
 import { Location, useLocation } from 'react-router-dom';
 
 export default function withLocation<P>(
-  WrappedComponent: React.ComponentType<P & { location: Location }>,
+  WrappedComponent: React.ComponentType<
+    React.PropsWithChildren<React.PropsWithChildren<P & { location: Location }>>
+  >,
 ) {
   return function WithLocation(props: Omit<P, 'location'>) {
     const location = useLocation();
index 310a2ab2c85a7ac384d8111124aaa451b99f8213..236a9b7a91b9bcfba45be3c6ed575488834ab5b7 100644 (file)
@@ -46,7 +46,9 @@ export interface WithNotificationsProps {
 }
 
 export function withNotifications<P>(
-  WrappedComponent: React.ComponentType<P & WithNotificationsProps>,
+  WrappedComponent: React.ComponentType<
+    React.PropsWithChildren<React.PropsWithChildren<P & WithNotificationsProps>>
+  >,
 ) {
   class Wrapper extends React.Component<P, State> {
     mounted = false;
index 329c601e0eca6a7f6efb77e6505333c2bbaa5120..b352d94c2685404bcdf847c43eb1c68769b0c878 100644 (file)
@@ -45,8 +45,10 @@ export interface WithRouterProps {
 }
 
 export function withRouter<P extends Partial<WithRouterProps>>(
-  WrappedComponent: React.ComponentType<P>,
-): React.ComponentType<Omit<P, keyof WithRouterProps>> {
+  WrappedComponent: React.ComponentType<React.PropsWithChildren<React.PropsWithChildren<P>>>,
+): React.ComponentType<
+  React.PropsWithChildren<React.PropsWithChildren<Omit<P, keyof WithRouterProps>>>
+> {
   function ComponentWithRouterProp(props: P) {
     const router = useRouter();
     const params = useParams();
@@ -55,10 +57,9 @@ export function withRouter<P extends Partial<WithRouterProps>>(
     return <WrappedComponent {...props} location={location} params={params} router={router} />;
   }
 
-  (ComponentWithRouterProp as React.FC<P>).displayName = getWrappedDisplayName(
-    WrappedComponent,
-    'withRouter',
-  );
+  (
+    ComponentWithRouterProp as React.FC<React.PropsWithChildren<React.PropsWithChildren<P>>>
+  ).displayName = getWrappedDisplayName(WrappedComponent, 'withRouter');
 
   return ComponentWithRouterProp;
 }
index 582ab09512381e6e4b94c1d6ffd9233aeb87784a..9f410cdc7828f5b3706c09678e18cc1f29e782d1 100644 (file)
@@ -28,8 +28,12 @@ export interface WithScrollToProps {
 const TOP_OFFSET = 200;
 const BOTTOM_OFFSET = 10;
 
-export function withScrollTo<P>(WrappedComponent: React.ComponentClass<P>) {
-  return class Wrapper extends React.Component<P & Partial<WithScrollToProps>> {
+export function withScrollTo<P>(
+  WrappedComponent: React.ComponentClass<React.PropsWithChildren<P>>,
+) {
+  return class Wrapper extends React.Component<
+    React.PropsWithChildren<P> & Partial<WithScrollToProps>
+  > {
     componentRef?: React.Component | null;
     node?: Element | Text | null;
 
index 0290f6d1f424e401125cb50669dc5532267ccc65..880f59ecc1137bf0d83fdcd9fe23efb8c674a0c0 100644 (file)
@@ -43,7 +43,9 @@ export default function ProjectLinkIcon({
   type,
   ...iconProps
 }: IconProps & ProjectLinkIconProps) {
-  const getIcon = (): FC<IconProps | MIUIIconProps> => {
+  const getIcon = (): FC<
+    React.PropsWithChildren<React.PropsWithChildren<IconProps | MIUIIconProps>>
+  > => {
     switch (type) {
       case 'issue':
         return miui ? PulseIcon : BugTrackerIcon;
index 27b9f619d04a126f594971728923efa069df26aa..fbf92f79843c97c05fe66f25e96cd5c310c34b33 100644 (file)
@@ -46,7 +46,10 @@ interface Props {
 interface State {
   initialPermissionsCount: Dict<number>;
 }
-export default class HoldersList extends React.PureComponent<Props, State> {
+export default class HoldersList extends React.PureComponent<
+  React.PropsWithChildren<Props>,
+  State
+> {
   state: State = { initialPermissionsCount: {} };
   componentDidUpdate(prevProps: Props) {
     if (this.props.filter !== prevProps.filter || this.props.query !== prevProps.query) {
index c27e5551f2c4ae8fc93c1001a6c1af55fbfaf73a..118a54a1ef8cab76fd0eddbdf9c33f88173e57b7 100644 (file)
@@ -37,7 +37,9 @@ interface Props {
   sections?: RuleDescriptionSection[];
 }
 
-const EDUCATION_PRINCIPLES_MAP: Dict<React.ComponentType> = {
+const EDUCATION_PRINCIPLES_MAP: Dict<
+  React.ComponentType<React.PropsWithChildren<React.PropsWithChildren<unknown>>>
+> = {
   defense_in_depth: DefenseInDepth,
   never_trust_user_input: NeverTrustUserInput,
 };
index 12394ea8705515f2c86614f3003352443da04779..162d2a742e7db2e311422fe5ca0ab9ecbf2b1d6c 100644 (file)
@@ -37,7 +37,9 @@ const BUILD_TOOLS_WITH_NO_ADDITIONAL_OPTIONS = [
 ];
 
 const BUILDTOOL_COMPONENT_MAP: {
-  [x in BuildTools]: React.ComponentType<LanguageProps>;
+  [x in BuildTools]: React.ComponentType<
+    React.PropsWithChildren<React.PropsWithChildren<LanguageProps>>
+  >;
 } = {
   [BuildTools.Maven]: Maven,
   [BuildTools.Gradle]: Gradle,
index b32dc36f650d58b54f1c608e1268e2f3296d5404..2daebd0f3970fa555adc1e4b6ebe0568558b585c 100644 (file)
@@ -273,7 +273,7 @@ export class PortalPopup extends React.Component<PortalPopupProps, State> {
   }
 }
 
-class PortalWrapper extends React.Component {
+class PortalWrapper extends React.Component<React.PropsWithChildren> {
   el: HTMLElement;
 
   constructor(props: {}) {
index 9cd80b75943d06966154640684e9fa43f893fbbb..23f7d388e14edcbdeaec24abde081853ea6ecf04 100644 (file)
@@ -46,7 +46,7 @@ export enum WorkspaceTypes {
   Component = 'component',
 }
 
-export default class Workspace extends React.PureComponent<{}, State> {
+export default class Workspace extends React.PureComponent<React.PropsWithChildren, State> {
   mounted = false;
 
   constructor(props: {}) {
index 52728e4f6394036dfb9a22996af51fdd3bdfa98f..2d5d7af9978f30da3b830296af39a756851d0823 100644 (file)
@@ -84,7 +84,7 @@ export default class WorkspaceHeader extends React.PureComponent<Props> {
 }
 
 interface WorkspaceHeaderButtonProps {
-  icon: React.SFC<IconProps>;
+  icon: React.FC<React.PropsWithChildren<React.PropsWithChildren<IconProps>>>;
   onClick: () => void;
   tooltip: string;
 }
index 5c037f24087a368af240a2179e472ec2243a2879..c0dc45a1ac827c7a5c195c02370c1e5dfe6859c0 100644 (file)
@@ -20,7 +20,7 @@
 import * as React from 'react';
 import { createPortal } from 'react-dom';
 
-export default class WorkspacePortal extends React.PureComponent {
+export default class WorkspacePortal extends React.PureComponent<React.PropsWithChildren> {
   el: HTMLElement;
 
   constructor(props: {}) {
index 8f8cc26489f1aea2d8dc6030e92705ff0f309343..d4b9704c79a74f7ac25aa6fad43cc846ecabeb42 100644 (file)
  */
 import { ComponentClass, FunctionComponent } from 'react';
 
-export type ComponentPropsType<T extends ComponentClass | FunctionComponent<any>> =
-  T extends ComponentClass<infer P> ? P : T extends FunctionComponent<infer P> ? P : never;
+export type ComponentPropsType<
+  T extends
+    | ComponentClass
+    | FunctionComponent<React.PropsWithChildren<React.PropsWithChildren<any>>>,
+> = T extends ComponentClass<infer P>
+  ? P
+  : T extends FunctionComponent<React.PropsWithChildren<React.PropsWithChildren<infer P>>>
+  ? P
+  : never;
 
 export function mockIntersectionObserver(): Function {
   let callback: Function;
index 78bba18898455ec900c334a0f6868c7bb95aec3c..ffbdff3369f6887e18fc5ce05fda911b04326d3c 100644 (file)
@@ -328,9 +328,15 @@ export function useRefreshBranches() {
 
 export function withBranchLikes<P extends { component?: Component }>(
   WrappedComponent: React.ComponentType<
-    P & { branchLikes?: BranchLike[]; branchLike?: BranchLike; isFetchingBranch?: boolean }
+    React.PropsWithChildren<
+      React.PropsWithChildren<
+        P & { branchLikes?: BranchLike[]; branchLike?: BranchLike; isFetchingBranch?: boolean }
+      >
+    >
   >,
-): React.ComponentType<Omit<P, 'branchLike' | 'branchLikes'>> {
+): React.ComponentType<
+  React.PropsWithChildren<React.PropsWithChildren<Omit<P, 'branchLike' | 'branchLikes'>>>
+> {
   return function WithBranchLike(p: P) {
     const { data, isFetching } = useBranchesQuery(p.component);
     return (
@@ -346,7 +352,11 @@ export function withBranchLikes<P extends { component?: Component }>(
 
 export function withBranchStatusRefresh<
   P extends { refreshBranchStatus: ReturnType<typeof useRefreshBranchStatus> },
->(WrappedComponent: React.ComponentType<P>): React.ComponentType<Omit<P, 'refreshBranchStatus'>> {
+>(
+  WrappedComponent: React.ComponentType<React.PropsWithChildren<React.PropsWithChildren<P>>>,
+): React.ComponentType<
+  React.PropsWithChildren<React.PropsWithChildren<Omit<P, 'refreshBranchStatus'>>>
+> {
   return function WithBranchStatusRefresh(props: P) {
     const refresh = useRefreshBranchStatus();
 
index ea95b30ffc6148381386d8aaf5b0a3c88bba38f3..84faf6ffa497ce19664c0af39fc803d095c15b06 100644 (file)
@@ -18,4 +18,5 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-export type FCProps<T extends React.FunctionComponent<any>> = Parameters<T>[0];
+export type FCProps<T extends React.FunctionComponent<React.PropsWithChildren<any>>> =
+  Parameters<T>[0];