Reputation: 17026
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?
Upvotes: 0
Views: 243
Reputation: 333
Okay I will try it from phone Sorry for formatting
import {AnyAction, combineReducers} from "redux";
const ADD_QUESTION = "ADD_QUESTION";
export interface Question {
id: number,
text: string
}
interface State {
nextId: number,
items: Question[]
}
const initialState: State = {nextId: 0, items: []}
const questions = (state = initialState, action: AnyAction): State => {
switch (action.type) {
case ADD_QUESTION:
return {
...state,
items: action.items,
nextId: action.nextId
};
default:
return state
}
};
export const reducers = combineReducers({
questions
});
That's how I see your reducer
Then in component in mapStateToProps questions: state.questions.items
Upvotes: 1