Búsqueda de sitios web

javascript - Cómo usar los enlaces de TypeScript de Redux 4.0 con redux-thunk


Estoy teniendo problemas para usar los nuevos enlaces de TS para Redux 4.0 con redux-thunk. He recreado el problema convirtiendo el ejemplo básico de Redux "Lista de Tareas" a TypeScript (repo aquí), y haciendo que la acción de Agregar Tarea sea un thunk. El problema es el mismo que se informa aquí: Argument of type 'ThunkAction' is not assignable to parameter of type 'AnyAction'. Property 'type' is missing in type 'ThunkAction'.

Básicamente, puedo hacer que funcione, pero estoy usando any en un par de lugares donde no creo que debería. Un lugar es index.tsx#L14, donde agrego el middleware thunk a la tienda:

const store = createStore(
  rootReducer,
  applyMiddleware(thunk as ThunkMiddleware<IRootState, any>)
);

Si uso cualquier cosa que no sea any allí, entonces la siguiente línea genera el error:

store.dispatch(addTodo('Use redux-thunk'));

El otro lugar es AddTodo.tsx#L7, donde declaro la propiedad dispatch que es inyectada por la función connect:

interface IAddTodoProps {
  dispatch: Dispatch<any>;
}

const AddTodo = ({ dispatch }: IAddTodoProps) => {
  ...
}
export default connect()(AddTodo);

En ambos lugares, el any sobrescribe un tipo que debe extender Action<any>. Action requiere un atributo type, que por supuesto un thunk no tiene. ¿Cómo puedo declarar estos tipos para que la función dispatch acepte un thunk?

Pregunta relacionada
PR relevante

Respuesta #1

diff --git a/src/containers/AddTodo.tsx b/src/containers/AddTodo.tsx
index e49ac4a..20a93d6 100644
--- a/src/containers/AddTodo.tsx
+++ b/src/containers/AddTodo.tsx
@@ -1,10 +1,12 @@
 import * as React from 'react';
 import { connect } from 'react-redux';
-import { Dispatch } from 'redux';
+import { ThunkDispatch } from 'redux-thunk';
+import { AnyAction } from 'redux';
 import { addTodo } from '../actions';
+import { IRootState } from '../reducers/index';

 interface IAddTodoProps {
-  dispatch: Dispatch<any>;
+  dispatch: ThunkDispatch<IRootState,any,AnyAction>;
 }

 const AddTodo = ({ dispatch }: IAddTodoProps) => {

Respuesta #2

La respuesta a esta pregunta (y a muchas otras) resultó ser: usar Redux Toolkit.

La configuración de la tienda es muy sencilla:

// src/redux/store.ts
import { configureStore } from '@reduxjs/toolkit';
import reducer from './reducers';

const store = configureStore({ reducer });

export type AppDispatch = typeof store.dispatch;

export default store;

Luego, al usar el hook useDispatch de react-redux, simplemente escríbelo como AppDispatch:

// src/components/App.tsx
import { useDispatch } from 'react-redux';
import { AppDispatch } from '../redux/store';

const App = () => {
  const dispatch: AppDispatch = useDispatch();
  // ...
}

Artículos relacionados