Skip to content

Commit

Permalink
[typescript] Add component field to *Props types (#38084)
Browse files Browse the repository at this point in the history
Co-authored-by: sai6855 <60743144+sai6855@users.noreply.github.com>
  • Loading branch information
michaldudak and sai6855 committed Jul 27, 2023
1 parent d428acb commit bca4565
Show file tree
Hide file tree
Showing 82 changed files with 751 additions and 190 deletions.
4 changes: 3 additions & 1 deletion packages/mui-material/src/Accordion/Accordion.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ declare const Accordion: OverridableComponent<AccordionTypeMap>;
export type AccordionProps<
RootComponent extends React.ElementType = AccordionTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<AccordionTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<AccordionTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default Accordion;
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ declare const AccordionSummary: ExtendButtonBase<AccordionSummaryTypeMap>;
export type AccordionSummaryProps<
RootComponent extends React.ElementType = AccordionSummaryTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<AccordionSummaryTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<AccordionSummaryTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default AccordionSummary;
4 changes: 3 additions & 1 deletion packages/mui-material/src/AppBar/AppBar.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ declare const AppBar: OverridableComponent<AppBarTypeMap>;
export type AppBarProps<
RootComponent extends React.ElementType = AppBarTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<AppBarTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<AppBarTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default AppBar;
4 changes: 3 additions & 1 deletion packages/mui-material/src/Avatar/Avatar.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ declare const Avatar: OverridableComponent<AvatarTypeMap>;
export type AvatarProps<
RootComponent extends React.ElementType = AvatarTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<AvatarTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<AvatarTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default Avatar;
4 changes: 3 additions & 1 deletion packages/mui-material/src/Backdrop/Backdrop.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ declare const Backdrop: OverridableComponent<BackdropTypeMap>;
export type BackdropProps<
RootComponent extends React.ElementType = BackdropTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<BackdropTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<BackdropTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default Backdrop;
4 changes: 3 additions & 1 deletion packages/mui-material/src/Badge/Badge.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ declare const Badge: OverridableComponent<BadgeTypeMap>;
export type BadgeProps<
RootComponent extends React.ElementType = BadgeTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<BadgeTypeMap<RootComponent, AdditionalProps>, RootComponent>;
> = OverrideProps<BadgeTypeMap<RootComponent, AdditionalProps>, RootComponent> & {
component?: React.ElementType;
};

export default Badge;
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ declare const BottomNavigation: OverridableComponent<BottomNavigationTypeMap>;
export type BottomNavigationProps<
RootComponent extends React.ElementType = BottomNavigationTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<BottomNavigationTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<BottomNavigationTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default BottomNavigation;
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ declare const BottomNavigationAction: ExtendButtonBase<
export type BottomNavigationActionProps<
RootComponent extends React.ElementType = ButtonBaseTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<BottomNavigationActionTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<BottomNavigationActionTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default BottomNavigationAction;
4 changes: 3 additions & 1 deletion packages/mui-material/src/Breadcrumbs/Breadcrumbs.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ declare const Breadcrumbs: OverridableComponent<BreadcrumbsTypeMap>;
export type BreadcrumbsProps<
RootComponent extends React.ElementType = BreadcrumbsTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<BreadcrumbsTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<BreadcrumbsTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default Breadcrumbs;
4 changes: 3 additions & 1 deletion packages/mui-material/src/Button/Button.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ declare const Button: ExtendButtonBase<ButtonTypeMap>;
export type ButtonProps<
RootComponent extends React.ElementType = ButtonTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<ButtonTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<ButtonTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default Button;
41 changes: 41 additions & 0 deletions packages/mui-material/src/Button/Button.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react';
import Button, { ButtonProps } from '@mui/material/Button';
import MaterialUiLink, { LinkProps as MaterialUiLinkProps } from '@mui/material/Link';
import { Link as ReactRouterLink, LinkProps } from 'react-router-dom';
import { expectType } from '@mui/types';

Expand All @@ -9,10 +10,47 @@ const TestOverride = React.forwardRef<HTMLDivElement, { x?: number }>((props, re
<div ref={ref} />
));

type CustomLinkProps = MaterialUiLinkProps<typeof ReactRouterLink, LinkProps>;
const CustomLink: React.FC<React.PropsWithChildren<CustomLinkProps>> = ({ children, ...props }) => {
return (
<MaterialUiLink component={ReactRouterLink} {...props}>
{children}
</MaterialUiLink>
);
};

function FakeIcon() {
return <div>Icon</div>;
}

const props1: ButtonProps<'div'> = {
component: 'div',
onChange: (event) => {
expectType<React.FormEvent<HTMLDivElement>, typeof event>(event);
},
};

const props2: ButtonProps = {
onChange: (event) => {
expectType<React.FormEvent<HTMLButtonElement>, typeof event>(event);
},
};

const props3: ButtonProps<typeof TestOverride> = {
component: TestOverride,
x: 2,
};

const props4: ButtonProps<typeof TestOverride> = {
component: TestOverride,
// @ts-expect-error TestOverride does not accept incorrectProp
incorrectProp: 3,
};

const props5: ButtonProps<typeof TestOverride> = {
component: TestOverride,
};

const buttonTest = () => (
<div>
<Button>I am a button!</Button>
Expand All @@ -36,6 +74,9 @@ const buttonTest = () => (
<Button component={ReactRouterLink} to="/open-collective">
Link
</Button>
<Button component={CustomLink} to="/some-route">
Link
</Button>
<Button href="/open-collective">Link</Button>
{/* By default the underlying component is a button element */}
<Button
Expand Down
4 changes: 3 additions & 1 deletion packages/mui-material/src/ButtonBase/ButtonBase.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ declare const ButtonBase: ExtendButtonBase<ButtonBaseTypeMap>;
export type ButtonBaseProps<
RootComponent extends React.ElementType = ButtonBaseTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<ButtonBaseTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<ButtonBaseTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export interface ButtonBaseActions {
focusVisible(): void;
Expand Down
4 changes: 3 additions & 1 deletion packages/mui-material/src/ButtonGroup/ButtonGroup.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ declare const ButtonGroup: OverridableComponent<ButtonGroupTypeMap>;
export type ButtonGroupProps<
RootComponent extends React.ElementType = ButtonGroupTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<ButtonGroupTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<ButtonGroupTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default ButtonGroup;
8 changes: 5 additions & 3 deletions packages/mui-material/src/Card/Card.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { SxProps } from '@mui/system';
import { DistributiveOmit } from '@mui/types';
import { OverridableComponent, OverrideProps } from '@mui/material/OverridableComponent';
import { Theme } from '..';
import { PaperProps } from '../Paper';
import { PaperOwnProps } from '../Paper';
import { CardClasses } from './cardClasses';

// TODO: v6 remove this interface, it is not used
Expand All @@ -14,7 +14,7 @@ export interface CardTypeMap<
DefaultComponent extends React.ElementType = 'div',
> {
props: AdditionalProps &
DistributiveOmit<PaperProps, 'classes'> & {
DistributiveOmit<PaperOwnProps, 'classes'> & {
/**
* Override or extend the styles applied to the component.
*/
Expand Down Expand Up @@ -49,6 +49,8 @@ declare const Card: OverridableComponent<CardTypeMap>;
export type CardProps<
RootComponent extends React.ElementType = CardTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<CardTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<CardTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default Card;
34 changes: 34 additions & 0 deletions packages/mui-material/src/Card/Card.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as React from 'react';
import Card from '@mui/material/Card';
import { expectType } from '@mui/types';

const CustomComponent: React.FC<{ stringProp: string; numberProp: number }> =
function CustomComponent() {
return <div />;
};

function CardTest() {
return (
<div>
<Card />
<Card elevation={4} />
<Card
onClick={(event) => {
expectType<React.MouseEvent<HTMLDivElement, MouseEvent>, typeof event>(event);
}}
/>
<Card
component="a"
href="test"
onClick={(event) => {
expectType<React.MouseEvent<HTMLAnchorElement, MouseEvent>, typeof event>(event);
}}
/>
<Card component="a" href="test" />

<Card component={CustomComponent} stringProp="test" numberProp={0} />
{/* @ts-expect-error missing stringProp and numberProp */}
<Card component={CustomComponent} />
</div>
);
}
4 changes: 3 additions & 1 deletion packages/mui-material/src/CardActionArea/CardActionArea.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ declare const CardActionArea: ExtendButtonBase<
export type CardActionAreaProps<
RootComponent extends React.ElementType = ButtonBaseTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<CardActionAreaTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<CardActionAreaTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default CardActionArea;
4 changes: 3 additions & 1 deletion packages/mui-material/src/CardContent/CardContent.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ declare const CardContent: OverridableComponent<CardContentTypeMap>;
export type CardContentProps<
RootComponent extends React.ElementType = CardContentTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<CardContentTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<CardContentTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default CardContent;
18 changes: 9 additions & 9 deletions packages/mui-material/src/CardHeader/CardHeader.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,38 @@ interface ComponentProp {
component?: React.ElementType;
}

<CardHeader component={CustomComponent} stringProp="s" numberProp={2} />;

function createElementBasePropMixedTest() {
React.createElement<CardHeaderProps<DefaultComponent, ComponentProp>>(CardHeader);
React.createElement<CardHeaderProps<DefaultComponent, ComponentProp>>(CardHeader, {
component: 'div',
});
// ExpectError: type system should be demanding the required props of "CustomComponent"
React.createElement<CardHeaderProps<DefaultComponent, ComponentProp>>(CardHeader, {
// @ts-expect-error required props are missing
React.createElement<CardHeaderProps<typeof CustomComponent, ComponentProp>>(CardHeader, {
component: CustomComponent,
});
// @ts-expect-error
React.createElement<CardHeaderProps<DefaultComponent, ComponentProp>>(CardHeader, {
// This test shouldn't fail but does; stringProp & numberProp are required props of CustomComponent
React.createElement<CardHeaderProps<typeof CustomComponent, ComponentProp>>(CardHeader, {
component: CustomComponent,
stringProp: '',
numberProp: 0,
});
React.createElement<CardHeaderProps>(CardHeader, {
disableTypography: true,
});
// @ts-expect-error
// @ts-expect-error CardHeader does not accept unknownProp
React.createElement<CardHeaderProps<DefaultComponent, {}, React.ElementType>>(CardHeader, {
unknownProp: 'shouldNotWork',
});
// @ts-expect-error
// @ts-expect-error disableTypography does not accept strings
React.createElement<CardHeaderProps>(CardHeader, {
disableTypography: 'hello',
});
// @ts-expect-error
// @ts-expect-error disableTypography does not accept numbers
React.createElement<CardHeaderProps>(CardHeader, {
disableTypography: 1,
});
// @ts-expect-error
// @ts-expect-error `component` is not a valid element
React.createElement<CardHeaderProps<any, ComponentProp>>(CardHeader, {
component: 'incorrectElement',
});
Expand Down
4 changes: 3 additions & 1 deletion packages/mui-material/src/CardMedia/CardMedia.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ declare const CardMedia: OverridableComponent<CardMediaTypeMap<{}, 'div'>>;
export type CardMediaProps<
RootComponent extends React.ElementType = 'div',
AdditionalProps = {},
> = OverrideProps<CardMediaTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<CardMediaTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default CardMedia;
4 changes: 3 additions & 1 deletion packages/mui-material/src/Chip/Chip.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ declare const Chip: OverridableComponent<ChipTypeMap>;
export type ChipProps<
RootComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<ChipTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<ChipTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default Chip;
4 changes: 3 additions & 1 deletion packages/mui-material/src/Container/Container.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ declare const Container: OverridableComponent<ContainerTypeMap>;
export type ContainerProps<
RootComponent extends React.ElementType = ContainerTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<ContainerTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<ContainerTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default Container;
2 changes: 1 addition & 1 deletion packages/mui-material/src/Dialog/Dialog.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export interface DialogProps extends StandardProps<ModalProps, 'children'> {
* Props applied to the [`Paper`](/material-ui/api/paper/) element.
* @default {}
*/
PaperProps?: Partial<PaperProps>;
PaperProps?: Partial<PaperProps<React.ElementType>>;
/**
* Determine the container for scrolling the dialog.
* @default 'paper'
Expand Down
19 changes: 16 additions & 3 deletions packages/mui-material/src/Dialog/Dialog.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import * as React from 'react';
import { Dialog } from '@mui/material';
import Dialog from '@mui/material/Dialog';
import { PaperProps } from '@mui/material/Paper';
import { expectType } from '@mui/types';

function optionalChildrenTest() {
<Dialog open />;
const paperProps: PaperProps<'span'> = {
component: 'span',
onClick: (event) => {
expectType<React.MouseEvent<HTMLSpanElement, MouseEvent>, typeof event>(event);
},
};
function Test() {
return (
<React.Fragment>
<Dialog open />;
<Dialog open PaperProps={paperProps} />;
</React.Fragment>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ declare const DialogContentText: OverridableComponent<DialogContentTextTypeMap>;
export type DialogContentTextProps<
RootComponent extends React.ElementType = DialogContentTextTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<DialogContentTextTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<DialogContentTextTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default DialogContentText;
4 changes: 3 additions & 1 deletion packages/mui-material/src/DialogTitle/DialogTitle.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ declare const DialogTitle: OverridableComponent<DialogTitleTypeMap>;
export type DialogTitleProps<
RootComponent extends React.ElementType = DialogTitleTypeMap['defaultComponent'],
AdditionalProps = { component?: React.ElementType },
> = OverrideProps<DialogTitleTypeMap<AdditionalProps, RootComponent>, RootComponent>;
> = OverrideProps<DialogTitleTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default DialogTitle;
Loading

0 comments on commit bca4565

Please sign in to comment.