situation
'user' does not exist on type 'DefaultRootState'. I've tried to solve it but I've not come up with the solution.this is my repo
error
C:/Users/taiga/Github/Typescript/typescript-admin/admin/src/secure/components/Nav.tsx
TypeScript error in C:/Users/taiga/Github/Typescript/typescript-admin/admin/src/secure/components/Nav.tsx(44,50):
Property 'user' does not exist on type 'DefaultRootState'. TS2339
Nav.tsx
class Nav extends Component<{ user: User }> {
state = {
redirect: false
};
handleClick = async () => {
await axios.post('logout', {});
this.setState({
redirect: true
});
};
render() {
if (this.state.redirect) {
return <Redirect to={'/login'} />;
}
return (
<nav className="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
<ul className="my-2 my-md-0 mr-md-3">
<Link to={'/profile'} className="p-2 text-white">
{this.props.user.name}
</Link>
</ul>
</nav>
);
}
}
export default connect((state) => ({ user: state.user }))(Nav);
user.ts
mport { Role } from './role';
export class User {
id: number;
first_name: string;
last_name: string;
email: string;
role: Role;
permissions: string[];
constructor(
id = 0,
first_name = '',
last_name = '',
email = '',
role = new Role(),
permissions: string[] = []
) {
this.id = id;
this.first_name = first_name;
this.last_name = last_name;
this.email = email;
this.role = role;
this.permissions = permissions;
}
setUserReducer.ts
import { User } from '../../classes/user';
const setUserReducer = (
state = { user: new User() },
action: { type: string; user: User }
) => {
switch (action.type) {
case 'SET_USER':
return {
...state,
user: action.user
};
default:
return state;
}
};
export default setUserReducer;
The problem is that the connect HOC doesn't know that the type of state is the type of your specific app's state and not just any state type. When it doesn't know the type of your specific state, it assumes that the state is of type DefaultRootState, which is defined in the react-redux types package as an empty object {}.
There are multiple ways to address this. One possibility, as recommended by the types package, is to override the definition of DefaultRootState and replace it with the actual state interface of your app.
This interface can be augmented by users to add default types for the root state when using react-redux. Use module augmentation to append your own type definition in a your_custom_type.d.ts file. https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
Another possibility, which is simpler to implement, is to declare the expected type of the state within your mapStateToProps function.
export default connect((state: {user: User}) => ({ user: state.user }))(Nav);
Now typescript knows that your state has a property user with the type User.
You can also set the generic arguments on the connect function when you call it, though I would recommend the previous method over this.
export default connect<{user: User}, {}, {}, {user: User}>((state) => ({ user: state.user }))(Nav);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With