-
-
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
[typescript] Smarter logic? #8063
Comments
So you can provide a |
@oliviertassinari I can't because I am using typescript and you have incorrect typings, so it complains that property |
This is also linked to #8043 |
cc @benbayard |
@benbayard I think this way should work for router links: <Button component={props => <RouterLink {...props} to="/" />} /> @nenadalm and also for simple link: <Button component={props => <a {...props} href="/" target="_blank" />} /> @oliviertassinari In TS typings |
We had this "smarter logic" in the typings, but it didn't work out like we wanted it to :-/ The only thing we can do is to allow all possiblities on the component. Meaning, allow all props from |
Talking about typings, ButtonProps (and probable others) for example miss style?: React.CSSProperties from its typing, and also some (all?) components miss stuff available to all react components such as tabIndex. v0.xx types were ok in this regard. PS: the original typings extend their props with |
@mctep That looks fine to be, but it should be noted that inline lambdas are highly unperformant. If I were to write docs for this I would write it as:
|
@ALL I guess the easy fix would just be to make What you all think? |
Best would be to type it as good as typescript allows (so whitelist all possible allowed properties). |
What about using Pick from the react types we may need?
so we could do something like
that way the types would be always in sync with react ones. |
@xaviergonz Why are we picking some properties out of button? Is it because there are some that are not supported. If so, you can use an
|
I didn't even know that was possible in TS oO |
We're actually using this because some of the native APIs and the APIs of But I think this discussion goes a little bit in the wrong direction. Why should we pick or omit things from the native elements. @nenadalm wrote:
This is actually why we didn't decide on that yet and the typings are (actually) kinda broken. IMHO the typings for |
I'd rather have the code compile and maybe get some runtime warnings from proptypes than having to use hacks like what I'm using right now for untyped properties, e.g:
|
@sebald I asked the same question, why are we picking any thing? (I'd prefer omiting over picking). I think the component prop is perfect for creating a type-safe component until typescript can get bi-furcating types. |
@xaviergonz With the proposed approach this would actually not be necessary, since @benbayard Could you explain to me what you mean by "the component prop is perfect for creating a type-safe component"? |
I made a PR with the mentioned approach, so when @oliviertassinari cuts a release on the weekend the typings will (hopefully) be better for everyone. If this is not enough, I'll add the index signature. Notet that this will affect the following components:
|
@sebald Great! :) |
Hi, How would you type/fix this : <ListItem
component={Link}
to="/about"
> I have the following error: |
You can always use spread and <ListItem
component={Link}
{...{ to: '/about' } as any}
> Though you will lose type safety. I am not sure if |
Ideally The same goes for several others component as |
It might be worth considering adding button?: boolean;
component?: React.ReactType;
+ additionalProps: {};
dense?: boolean;
disabled?: boolean;
disableGutters?: boolean;
divider?: boolean; to <ListItem
component={Link}
additionalProps={{ to: "/about" }}
/> without being hampered by the type system. An escape hatch like this would allow us to avoid compromising the strict typing of the rest of the props, and just say, "if you're providing your own component you can throw whatever extra properties you like in here... use at your own risk!" This will of course require a corresponding change to the |
Here's a less invasive and more type safe idea: define a HOC declare const overrideComponent:
<BaseProps extends { component?: React.ReactType}>(BaseComponent: React.ComponentType<BaseProps>) =>
<CustomProps>(CustomComponent: React.ComponentType<CustomProps>) =>
React.ComponentType<Replace<BaseProps, CustomProps>> whose implementation is just const overrideComponent = BaseComponent => CustomComponent => props =>
<BaseComponent component={CustomComponent} {...props} /> and then you can do const LinkListItem = overrideComponent(ListItem)(Link)
const elem = <LinkListItem to="/about" /> and it's completely type safe. On the decorated component you can provide all properties from the base component as well as the custom component, which matches the underlying semantics. |
A better alternative where you will not risk a property collision: <ListItem component={props => <Link {...props} to="/about" />}>
// ...
</ListItem> I have always considered the below pattern an elegant "hack" (it's harder to understand). <ListItem component={Link} to="/about">
// ...
</ListItem> It's also why you won't find this third API with Material-UI. It's a tradeoff between the two previous ones that suffer limitations without being much simpler. <ListItem component={<Link to="/about" />}>
// ...
</ListItem> |
@oliviertassinari that's a great way to do it! |
just tested @oliviertassinari solution, worked fine, no more typings issue 👍 |
This no longer works as per "@types/react": "^16.0.36", |
If you're running into issues using Material-UI, please don't reply to old and closed issues. Open up a new one and provide as much info as possible. This way it's more likely we can help. |
Problem description
Button
hashref
prop. If that prop is set,a
element is used to render the button (https://material-ui-1dab0.firebaseapp.com/api/button/). It would be nice ifButton
had alsotarget
property.Versions
The text was updated successfully, but these errors were encountered: