-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Can't pass props with excess properties #15463
Comments
You can do like below, but may get a warning about scopes being unused. export class App extends React.Component<Props, State> {
render() {
const { scopes, ...otherProps } = this.props;
return <Content {...otherProps} />;
}
} |
The same question. It's hard to understand why the following code will not compile anymore in v2.3 import * as React from "react";
interface ComponentProps {
property1: string;
property2: number;
}
export default function Component(props: ComponentProps) {
return (
<AnotherComponent {...props} />
);
}
interface AnotherComponentProps {
property1: string;
}
function AnotherComponent({ property1 }: AnotherComponentProps) {
return (
<span>{property1}</span>
);
} due to the error
Btw, the same code without jsx will compile with no error import * as React from "react";
interface ComponentProps {
property1: string;
property2: number;
}
export default function Component(props: ComponentProps) {
return React.createElement<AnotherComponentProps>(AnotherComponent, props);
}
interface AnotherComponentProps {
property1: string;
}
function AnotherComponent({ property1 }: AnotherComponentProps) {
return React.createElement("span", null, property1);
} |
A little bit different but still the same. export default class Panel extends React.Component<void, void> {
...
} now leads to this error
Had to change |
@luca-moser @luggage66 @etecture-plaube @pomadin The reason for change in behavior is that in 2.3,
I will get the PR up today and the fix should be in for tomorrow nightly if you would like to give that a try! |
@yuit If you only allow the second case in your list, it will still break a lot of components. Parent components often spread their Props object further and compute some additional things which are passed explicitly. Here's an example from my actual codebase: this.props.users.sort((a, b) => a.name > b.name ? 1 : -1).forEach((user: User) => {
if (user._filtered) return;
users.push(<UserCard {...this.props} key={user.id} user={user}/>); // this would error out
}); |
@luca-moser Thanks for feed back! Here is the second thought :
|
I agreed with @luca-moser, it's common case to extend the props or to override some ones. @yuit, the final solution looks acceptable as the 1st case (only explicitly attrs...) fits no jsx case. interface Props {
p1: string;
}
function fn(props: Props) {
}
fn({ p1: "", p2: 1 }); // ERROR: Object literal may only specify known properties... |
I also have a lot of For case |
@IIIristraM could you share more repo for both cases. the Second may get fixed in the nightly. IF you could share a full repo, I can take a look |
both cases take place in this example |
Where an error occur? Is it at here |
Yes, this is right code line. Definitions for |
@IIIristraM Thanks! I am able to see this error |
@luca-moser @luggage66 @pomadin @etecture-plaube @IIIristraM We have fix for original in the master. It should be out for nightly tonight. Give that a try and let us know. We will have this fix for 2.3.3 as well. @IIIristraM Note: the fix doesn't address " Spread types may only be created from object types" I will get that in another PR -> Update we have the fix into master nightly. Give it a try and let us know |
@yuit I have compiled my code via build 2.4.0-dev.20170509, the error is gone. So I am waiting for v2.3.3 to move on. |
@pomadin thanks for the feedbacks. We will have this fix in for 2.3.3 |
export function makeP<P>(Ctor: React.ComponentClass<P>): React.ComponentClass<P> {
return class extends React.PureComponent<P, void> {
public render(): JSX.Element {
return (
<Ctor {...this.props }/>
);
}
};
} @yuit for |
Hi @pomadin , I met the same problem and then found the reason that is |
I had the same issue which I resolved by extending
so I could render the table as follows:
|
Started using v 2.6.1 today and can still see a lot of errors similar to ones discussed here, i.e.
this happens for all: |
I am not familiar with |
I just added react-router-dom to a https://github.com/wmonk/create-react-app-typescript app and added the following code and got a similar error: any ideas? |
@quantuminformation use RouteComponentProps from export class Home extends React.Component<RouteComponentProps<void>, any> |
I'm using ConnectedRouter now and it just works, even with just: const Home = () => (
<div>
<h2>Home</h2>
</div>
) |
I'm also having issues with this interface RoleProps {
radius?: number;
size?: "small" | "medium" | "big";
look?: "primary" | "secondary" | "dark" | "light";
}
export class Button extends React.PureComponent<RoleProps> {
render() {
return (
<InternalButton {...this.props} > {this.props.children} </InternalButton>
)
}
}
// InternalButton has P = <RoleProps & Themer>
That should technically work as the common props should spread. |
Honestly, I just started using Typescript in a React project, and I've spent most of my time dealing with issues like this. It's a shame. |
@kevinSuttle can you file a new issue? This is labelled fixed. In case it's not fixed, can you explain how the error reproduces in your code? |
@sandersn Is this not sufficient enough for you #15463 (comment) ? |
@seivan What is the type of Themer? The intersection of RoleProps & Themer is too big to print in an error message, it looks like. |
@levsthings @mhegazy @sandersn Hey guys I am also stuck on this, been bashing my head all week. I keep getting this error:
|
Same here using React + Redux + Material-UI-Next. Seems those props are not injected properly. In my case, withStyles should have injected import withStyles, { WithStyles } from 'material-ui/styles/withStyles';
type PropsWithStyle = Props & WithStyles<'root'>
// WithStyle introduces classes property
class Controller extends React.Component<PropsWithStyle , State> {}
export default withWidth()(withStyles(styles)(connect(mapStateToProp)(SampleComponent))); |
Hey guys I got the same problem too,please help me <Button label="Force Update" onClick={() => {
// this.setState({splits});
setInterval(() => {
let width = this.state.width - 10;
this.setState({width});
}, 100);
}}></Button>
|
@ILL35T @nileshgulia1 |
@sandersn Sorry to get back to you so late. I made it simple for testing, it's just export interface Themer {
theme: { color: string }
} What I am trying to figure out that is ambiguous and unclear (a failure I attribute to TypeScript or at least its documentation) is out the spread operator works overall. Perhaps you could help clear that up here, and we could take a look at the documentation to make it less ambiguous. This seems like a bug (but obviously I could be wrong) Pick<RoleProps & Themer, "radius" | "size" | "look"> If we're picking properties then |
I am having same issue but only when I saperate out component and containers! Really fustrating :| |
Yes, I too am having the issue. If you pull in a container that gets its properties from a redux store, you cannot compile without specifying the properties. An example is it seems to occur with typescript and when you cast the connect back to the base type
If I do this to create a container and then use it in a page like this
If I leave off the 'as typeof MyList' in the connect of the container then the error goes away. However I lose being able to have type on the container |
I'm also having this exact same issue and I've spent the better part of the day scouring the internet trying to find what's wrong since this issue doesn't have an update. I've tried following different tutorials on different ways to connect redux with react. For the ~16 hours I've spent today on this I'm coming to the conclusion that React + Redux + TS doesn't work. Typescript: 2.7.2 Sample:
With this simple:
⬆️ One of a bunch of different ways I've tried. |
@mechanic22 It's not perfect, but I just did |
@tsteuwer you should let so if you do this
then it will be ok |
@levsthings I got the same issue, but I don't see any solution apart from what @PaitoAnderson suggested ( |
This issue is the reason I'm choosing Flow for my next project. |
@Peterabsolon Flow will have its own set of problems and not give the same runtime guarantees as TS. But yeah, the compiler errors could use some more work :) |
@seivan I looked at your example again and I noticed that export class InternalButton extends React.Component<RoleProps & Themer> { }
expert class Button extends React.PureComponent<RoleProps> {
render() {
return <InternalButton {...this.props}></InternalButton> The error I get is then "Property 'theme' is missing in '{ children: ReactNode[], radius?: number, size?: "small" ... }'." I can fix it by passing a return <InternalButton {...this.props} theme={{ color: 'brown' }}>{this.props.children}</InternalButton> Note that I don't know React that well -- I'm just following the types, so I don't know if theme is actually required at runtime. As far as I can tell, the above is equivalent to the typescript function calls: function InternalButton(props: RoleProps & Themer) { }
function Button(props: RoleProps) {
return InternalButton({ ...props, theme: { color: 'brown' } })
} And for those definitions, it makes sense to me that |
TypeScript Version: 2.3.1
Code
With the above mentioned version I can't spread Props objects anymore to child React components, when the Props don't match up 100%.
Expected behavior:
No error and there wasn't any on 2.2.1
Actual behavior:
error:
The text was updated successfully, but these errors were encountered: