I am trying to write a React Redux component using Typescript following the documentation in Redux Getting Started and Proper Typing of react-redux Connected Components and am getting a type error on my connect function.
My app uses Redux to maintain a table of questions.
state.tsx
import {AnyAction, combineReducers} from "redux";
const ADD_QUESTION = "ADD_QUESTION";
export interface Question {
id: number,
text: string
}
export interface State {
questions: QuestionsTable
}
interface QuestionsTable {
nextId: number,
questions: Question[]
}
const questions = (state: State = {questions: {nextId: 0, questions: []}}, action: AnyAction): State => {
const questions = state.questions;
switch (action.type) {
case ADD_QUESTION:
return {
...state,
questions: {
...questions,
nextId: questions.nextId + 1,
questions: questions.questions.concat([{id: questions.nextId, text: action.text}])
}
};
default:
return questions
}
};
export const reducers = combineReducers({
questions
});
A Questions component displays them. I use connect to create QuestionsContainer from that.
questions.tsx
import React from "react"
import {Question, State} from "../state";
import {connect} from "react-redux";
export type QuestionsProps = {
questions: Question[]
}
const Questions: React.FC<QuestionsProps> = ({questions}) => {
return (
<div>
<ul>
{questions.map(question => (
<li>{question.text}</li>
))}
</ul>
</div>
)
};
const mapStateToProps = (state: QuestionsTable): QuestionsProps => {
return {questions: state.questions.questions};
};
export const QuestionsContainer = connect<QuestionsProps>(mapStateToProps)(Questions);
My top-level app displays this container component.
App.tsx
import React from "react";
import "./App.css";
import {reducers} from "./state";
import {createStore} from "redux"
import {Provider} from "react-redux"
import {QuestionsContainer} from "./components/questions";
const store = createStore(reducers);
const App: React.FC = () => {
return (
<Provider store={store}>
<div className="App">
<QuestionsContainer/>
</div>
</Provider>
);
};
export default App;
I get a type error in my call to connect.
Error:(61, 59) TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type '(state: State) => QuestionsProps' is not assignable to parameter of type 'MapStateToPropsParam<QuestionsProps, {}, {}>'.
Type '(state: State) => QuestionsProps' is not assignable to type 'MapStateToPropsFactory<QuestionsProps, {}, {}>'.
Types of parameters 'state' and 'initialState' are incompatible.
Property 'questions' is missing in type '{}' but required in type 'State'.
If I suppress this error with @ts-ignore and log the value of questions passed to my Questions component I see this.
{"nextId":0,"questions":[]}
I can't figure out why the nextId field is there even though mapStateToProps dereferences state.questions.questions.
What is the correct way to set this up?