-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using Omit
in Typescript to remove props from end user breaks component={}
prop and type inference
#35026
Comments
Omit
in Typescript to remove props from end user breaks component
and type inferenceOmit
in Typescript to remove props from end user breaks component={}
prop and type inference
The problem seems to come from the lack of a type MyButtonProps = Omit<ButtonProps, 'disableFocusRipple' | 'disableRipple'> & {
component?: React.ElementType;
}; As for the second problem - why isn't the onChange parameter inferred correctly? type MySelectProps<T> = Omit<SelectProps<T>, 'defaultOpen'>;
const MySelect = function<T>(props: MySelectProps<T>) {
return <Select {...props} />;
}; |
@michaldudak Thank you for your reply and looking into this. I have managed to address the I have created an isolated example using a wrapped I think the complication stems from the fact that the export type ContainerProps<
D extends React.ElementType = ContainerTypeMap['defaultComponent'],
P = {}> and with me applying the suggested fix for // NOTE: Is `any` the right approach here?
// If not, how do I get the element type that was given to `component={}` here?
type MyContainerProps<T> = Omit<ContainerProps<any, T>, "disableGutters"> & {
component?: React.ElementType;
};
const MyContainer = function <T>(props: MyContainerProps<T>) {
return <Container {...props} />;
}; In the following usage, the props from {/* NOTE: The `elevation` prop is not working as expected, it should throw an error */}
<MyContainer maxWidth="sm" component={Surface} elevation={"test"}>
A container without the 'disableGutters' prop.
The props of the `component` given are not working as expected.
</MyContainer> The interface SurfaceProps {
elevation?: number;
emphasis?: "low" | "medium" | "high";
}
const Surface = styled("div")<SurfaceProps>(
({ theme, elevation = 1, emphasis }) => {
const colorMap: Record<SurfaceProps["emphasis"], string> = {
low: "green",
medium: "blue",
high: "red"
};
return {
backgroundColor: emphasis ? colorMap[emphasis] : "white",
boxShadow: `0px 2px ${elevation * 2}px black`,
padding: theme.spacing(2),
borderRadius: theme.shape.borderRadius
};
}
); If you have any ideas on where I am going wrong with this, I would appreciate your help once again :) |
In this case, IMO, your best bet would be to define the type of the component and its props the same way we do in Material UI itself. We use so-called "type maps" to define the props and default root component a given component uses and pass them to utility types: For a concrete example, I've forked your codesandbox and modified the types: https://codesandbox.io/s/confident-sun-652mrk?file=/src/App.tsx I understand it's not perfect and requires a fair share of typing but modeling polymorphic components in TypeScript is not a trivial task. Let me know if it helps. |
- Reverted MUI-packages to earlier versions found on dev. Current issue: mui/material-ui#35026
Duplicates
Latest version
Steps to reproduce 🕹
Link to live example: https://codesandbox.io/s/wandering-darkness-mevzqv?file=/src/App.tsx
Example shows this behaviour for a polymorphic component (
Button
) and a simpler component,Select
.Steps:
Select
andSelectProps
Omit
function to remove an optional prop,Omit<SelectProps, "defaultOpen">
component="a"
onButton
or loosing type inference of theSelect
value whereevent.target.value
becomesunknown
instead ofstring
(see example)Current behavior 😯
Removing props from the Typescript interface, breaks general types applying to the modified component.
For polymorphic components that support the
component="x"
prop, setting it will re-enable the Omit'ed prop.For other components, the components type inference breaks and event handler values result in
unknown
instead ofstring
or its appropriate type.Expected behavior 🤔
I would like to remove some of the defined props or prop values from the typescript types for components without breaking other typed functionality.
If I choose to
Omit
a prop, the other props should continue working as normal.Context 🔦
We are using Material UI Core (and MUI X Pro) to build an in-house Design System.
We want to make minimal changes/simplifications to the component types to guide our end-users towards using the components as we intend them to be used.
Material UI provides a rich interface of custom component options via its props and often times we would like to curate which props are available to our internal development teams that use our library.
In order to do so, our intend is to re-export MUI components with modified typescript types which "hide" the props we don't want our users to set/use.
Examples
Examples for
Button
andSelect
of this are below:This should result in 3 props not being suggested in the typescript intellisense:
disableFocusRipple
disableElevation
disableRipple
And should remove the
inherit
option from thecolor
prop.Wrong approach?
If this is the wrong approach for curating which props or which prop values are available to our development teams, I would love to learn the idiomatic way to do this as we really want to limit the scope of our end users (internal) to set props we don't want to support/use for brand consistency.
Your environment 🌎
npx @mui/envinfo
npx tsc --showConfig
The text was updated successfully, but these errors were encountered: