So I've just started to combine react, redux (react-redux) and typescript. But I can't seem to figure out something here, namely, why the child components inside of the App component require all of the props that I pass into the App component.
App component:
const App = ({contacts, user, activeUserId}: ApplicationState) => (
<div className="App">
<Sidebar contacts={contacts} />
<Main user={user} activeUserId={activeUserId}/>
</div>
);
const getContacts = ({contacts, user, activeUserId}: ApplicationState) => ({contacts, user, activeUserId});
export default connect(getContacts)(App);
Sidebar component:
const Sidebar = ({contacts}: ApplicationState) => {
let contactsValues: Array<Contacts> = contacts && Object.values(contacts);
return (
<aside className="Sidebar">
{contactsValues && contactsValues.map((contact: Contacts) => <User user={contact} key={contact.user_id}/>)}
</aside>
)
}
I don't think there's any reason to list the Main component here as well since its only an empty component but gives the same errors, so I will just go ahead an list the Interfaces:
export default interface Contacts {
email: string,
name: string,
profile_pic: string,
status: string,
user_id: string
}
export default interface ApplicationState {
contacts: Contacts,
user: object,
activeUserId: string | null
}
Actual error code: "TS2739: Type '{ contacts: Contacts; }' is missing the following properties from type 'ApplicationState': user, activeUserId"
So, both components ask to have all the props injected into them, even though they are not required inside the component itself. If I supply the components the everything works and I get no errors.
I'm pretty sure there's something wrong with my syntax or 'wiring' of the types.
Can we also get a explanation or a decent link to docs/materials that help us understand why this is happening?
If there is anything else that I should be including please let me know and I will provide!
Edit:
I've actually realized that its important to show the Main component too because this one also causes problems and some of the fixes you guys have suggested only fix the Sidebar component but not the Main.
Main component:
import React from "react";
import "./Main.scss";
import ApplicationState from "../../models/ApplicationState";
const Main = ({user, activeUserId}: ApplicationState) => {
return (
<main className="Main">
Main Stuff
</main>
)
}
Edit:
From what I've experimented with all of these answers I think the best solution would be to make everything in the interfaces optional, but if I do this then the contactsValues variable inside the Sidebar component throws: TS2322: Type 'any[] | undefined' is not assignable to type 'Contacts[]'. Type 'undefined' is not assignable to type 'Contacts[]'..