0
votes

Given the following components, I get an error about a missing isUpdating prop. How do I fix that?

Error:(87, 27) TS2322:Type '{ name: "Fred"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes> & Reado...'. Type '{ name: "Fred"; }' is not assignable to type 'Readonly'. Property 'isUpdating' is missing in type '{ name: "Fred"; }'.

interface ContaineeProps {
  name: string;
  isUpdating: string;
}

const Containee = (props: ContaineeProps) => <span>{props.name}</span>;

interface MapStateToProps {
  isUpdating: boolean;
}
const mapStateToProps = state => ({ isUpdating: state.years.yearsUpdating });

const ConnectedContainee = connect<MapStateToProps, null, ContaineeProps>(mapStateToProps)(Containee);


interface Container {
  name: string;
}

class Container extends React.Component<Container, {}> {
  render() {
    return (
      <ConnectedContainee name="Fred" />
    )
  }
}

edit: This question is more about best practices in a redux/react/typescript application and less about the reason for this error. Do I always have to have required props type information specified in two places (props interface for the component, and the interface for the mapStateToProps function)?

1
What is VehiclesFormProps?Oliver Charlesworth
@OliverCharlesworth Well crap, I thought I did such a careful job copy/pasting/editing a simplified example from my actual components. Turns out that actually I suck! (fixed my example)Dustin Wyatt

1 Answers

1
votes

The compile error you're receiving is correct. Given your ContaineeProps contains a property isUpdating, your component expects to be passed this property when you use it.

e.g. <ConnectedContainee name="Fred" isUpdating="testing" />

Given your question, I am wondering whetherisUpdating should be in ContaineeProps at all? If it's not then simply remove it and the compile error should go away.

If it is intended to be there then I would recommend giving it a different name as you already have an isUpdating prop in your MapStateToProps interface.

Update

If I understand your comment correctly you've added the isUpdating prop to your ContaineeProps to be able to access it within your component. To do this you don't need to add the property to both prop interfaces, I don't actually think that would work...

What you need to do is combine your interfaces so your component can have access to both interfaces that contain props passed in from parent components and props mapped in from redux.

Here's an example:

interface AllProps extends MapStateToProps, ContaineeProps {}

const Containee = (props: AllProps) => <span>{props.name} {props.isUpdating}</span>;

or

const Containee = (props: ContaineeProps & MapStateToProps) => <span>{props.name} {props.isUpdating}</span>;

props.isUpdating now refers to the property mapped in from the redux store. If you wanted to also store the isUpdating value locally you would use the components local state.