I am having trouble creating a store using Redux and TypeScript. Here is my actions.js file:
import { Action } from 'redux';
export interface ITodoAction extends Action {
todo:string;
}
export const ADD_TODO:string = 'ADD_TODO';
export function addTodo(todo:string):ITodoAction {
return {
type: ADD_TODO,
todo
};
}
I have exported an interface for a custom action named ITodoAction, which extends Action to include my custom property "todo.".
Now moving on to reducers.js:
import { Reducer } from 'redux';
import { ITodo } from '../interfaces';
import { ITodoAction, ADD_TODO } from '../actions';
let id:number = 0;
const generateId = ():number => id++;
interface ITodoState {
todos:Array<ITodo>
};
const defaultState:ITodoState = {
todos: []
};
export function todoReducer(state:ITodoState = defaultState, action:ITodoAction):ITodoState {
switch(action.type) {
case ADD_TODO:
return Object.assign({}, state, {
todos: [
{ id: generateId(), text: action.todo, completed: false },
...state.todos
]
});
default:
return state;
}
}
I have utilized ITodoAction from the previous actions.js file to define the todoReducer. The todoReducer returns an instance of ITodoState, which looks like this:
{
type: 'ADD_TODO',
todos: [ ITodo{}, ITodo{}, ITodo{}, ... ]
}
This is the ITodo interface that I used:
export interface ITodo {
id:number;
todo:string;
completed:boolean;
}
It is a simple object containing properties for id, text, and completed. However, when I attempted to create a store with the reducer as shown below, it failed:
import { createStore } from 'redux';
import todoReducer from './reducers';
export const store = createStore(todoReducer);
The error message states:
Argument of type 'typeof "/.../typescript-todo/src/ts/reducers/index"' is not assignable to parameter of type 'Reducer<{}>'...
Type 'typeof "/./typescript-todo/src/ts/reducers/index"' provides no match for the signature '<A extends Action>(state: {}, action: A): {}'
It seems that I need to fix my reducer, but I am unsure how to define it with Reducer<{}>. Every attempt I made resulted in similar errors. Why can't I simply use my basic reducer?
I came across numerous posts related to TypeScript and Redux, but they did not use Reducer<{}> or Action>T<. This has left me confused as to why they worked without these interfaces.
Upon further research, I found the type declaration of Redux and discovered what Reducer<{}> looks like:
export type Reducer<S> = <A extends Action>(state: S, action: A) => S;
My understanding is that Reducer<{}> is a function that returns the state. So why does my todoReducer not work with them? I tried with Reducer<ITodoState>, but it still did not work.
I am extremely confused now and feel like I must be missing something significant. I never imagined that using Redux with TypeScript would be so challenging.
Despite my best efforts, I seem to require assistance. Any advice would be greatly appreciated.