Typescript returns errors in Redux types
Quick question, I'm writting a React-native application with typescript and redux. Running into error when trying to connect() and can't seem to find a solution to the error. I assume its something wrong I did but after looking at it for couple hours can't find a reason.
Error:
Argument of type '(state: AppStateType) => { user: AppStateType; }' is not assignable to parameter of type 'MapStateToPropsParam<IMapStateToProps, void, {}>'.
Type '(state: AppStateType) => { user: AppStateType; }' is not assignable to type 'MapStateToProps<IMapStateToProps, void, {}>'.
Types of parameters 'state' and 'state' are incompatible.
Type '{}' is not assignable to type 'AppStateType'.
Property 'username' is missing in type '{}'.
When trying to connect(mapStateToProps):
export default connect<IMapStateToProps, Object, void>(*mapStateToProps*, mapDispatchToProps)(HomeScreen);
My Reducer:
import * as Immutable from 'seamless-immutable';
// our defined @types
import { AppStateType, ActionType } from '../../@types';
const appState: AppStateType = {
username: '',
password: '',
serviceCode: 0,
fetching: false
};
// enforce that state is immutable
export const initialState = Immutable.from(appState);
const userReducer = (state = initialState, action: ActionType) => {
switch (action.type) {
case 'FETCH_USER':
state = {
...state,
fetching: false
};
break;
case 'SET_USER':
state = {
...state,
fetching: false
};
break;
default:
break;
}
return state;
};
export default userReducer;
@types file:
// app state type
export type AppStateType = {
username: '';
password: '';
serviceCode: 0;
fetching: false;
};
export interface InterfaceSetUser {
type: 'SET_USER';
payload?: {};
}
export interface InterfaceFetchUser {
type: 'FETCH_USER';
payload?: {};
}
export type ActionType = InterfaceSetUser | InterfaceFetchUser;
Actions:
import { Dispatch } from 'react-redux';
export function SetUser(user: Object) {
return function(dispatch: Dispatch<{}>) {
dispatch({
type: 'SET_USER',
payload: user
});
};
}
Component:
import * as React from 'react';
import { View, Text } from 'react-native';
import { AppStateType, ActionType } from '../@types';
import { Dispatch, connect } from 'react-redux';
import { SetUser } from './../redux/actions/user.actions';
import { bindActionCreators } from 'redux';
interface IMapStateToProps {
username: '';
password: '';
serviceCode: 0;
fetching: false;
}
const mapStateToProps = (state: AppStateType) => ({
user: state
});
const mapDispatchToProps = (dispatch: any) => {
return bindActionCreators({
setUser: SetUser
}, dispatch);
};
class HomeScreen extends React.Component {
render() {
return(
<View>
<Text>
Home Screen
</Text>
</View>
);
}
}
export default connect<IMapStateToProps, Object, void>(mapStateToProps, mapDispatchToProps)(HomeScreen);
I'm relatively new to Typescript and Redux therefore can't wrap my head around the issue. Can you point me to the right direction here?
Your mapStateToProps()
should be returning a type of IMapStateToProps
ie it's expecting an object with the properties username
, password
, serviceCode
and fetching
. However you are returning an object from mapStateToProps()
with just a single property, user
.
That is answering the question you asked, however there are lots of issues with your code that I'm not sure you are aware about. For example, AppStateType
and IMapStateToProps
have strange definitions that I would expect to be:
export type AppStateType = {
username: string;
password: string;
serviceCode: number;
fetching: boolean;
};
HomeScreen
should extend something like React.Component<IMapStateToProps & { setUser: () => void}>
or whatever the definition of setUser
might be.
The type of mapDispatchToProps
is Object
in your connect()
. This is not accurate as it is really an object with a setUser
function.