Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

538
Vistas
TS2339: la propiedad 'tsReducer' no existe en el tipo 'DefaultRootState'

Luchando con la pregunta anterior. He visto preguntas similares pero no puedo resolverlo.

El siguiente código es mío intentando abrir y cerrar un cuadro de diálogo usando TypeScript por primera vez en un proyecto React existente que usa .js y .jsx.

 import Button from '@material-ui/core/Button'; import Dialog from '@material-ui/core/Dialog'; import DialogActions from '@material-ui/core/DialogActions'; import DialogContent from '@material-ui/core/DialogContent'; import {useDispatch, useSelector} from 'react-redux'; import {closeTsDialog} from '../actions/tsDialog' import {ActionTypes} from '../actions/types'; const TsApp = (): JSX.Element => { const dispatch = useDispatch(); // ERROR SHOWS UP ON LINE BELOW "state?.tsReducer?.isDialogOpen" const isDialogOpen = useSelector(state => state?.tsReducer?.isDialogOpen); const state = useSelector(s => s); console.log('->>>>>> state', state); // main tsx excluded to allow for posting on stackoverflow }; export default TsApp;
 import {TsDialogAction} from "../actions/tsDialog"; const initialState = { id: 0, isDialogOpen: false }; const tsReducer = (state: TsDialogAction = initialState, action: Action) => { switch (action.type) { case ActionTypes.closeDialog: { return {...state, isDialogOpen: false}; } case ActionTypes.openDialog: { return {...state, isDialogOpen: true}; } default: return state; } }; export default tsReducer;

importar {ActionTypes} desde './types';

interfaz de exportación TsDialogAction {isDialogOpen: número booleano: número}

interfaz de exportación CloseTsDialog { tipo: ActionTypes.closeDialog carga útil: TsDialogAction }

interfaz de exportación OpenTsDialog { tipo: ActionTypes.openDialog carga útil: TsDialogAction }

interfaz de exportación Incremento { tipo: ActionTypes.increment payload: TsDialogAction }

interfaz de exportación Decremento { tipo: ActionTypes.decrement payload: TsDialogAction }

exportar const closeTsDialog = (id: número) => ({tipo: ActionTypes.closeDialog, payload: id}); exportar const openTsDialog = (id: número) => ({tipo: ActionTypes.openDialog, payload: id}); export const incrementAction = (id: número) => ({tipo: ActionTypes.increment, payload: id}); export const decrementAction = (id: número) => ({tipo: ActionTypes.decrement, payload: id});

over 4 years ago · Santiago Trujillo
7 Respuestas
Responde la pregunta

0

Debe declarar el tipo de argumento de state en su selector, como:

 const isDialogOpen = useSelector( (state: RootState) => state.tsReducer.isDialogOpen);

Consulte los documentos de Redux sobre el uso de TypeScript , así como la página de documentos de React-Redux sobre escritura estática para ver ejemplos.

(Además, como nota estilística: no lo llame tsReducer en su estado raíz. Déle un nombre que coincida con los datos que está manejando, como state.ui ).

over 4 years ago · Santiago Trujillo Denunciar

0

Se queja del tipo. La solución rápida sería agregar any como tipo de estado.

La solución adecuada requerirá los siguientes dos pasos:

  1. Cree el tipo RootState en Root Reducer.
 export const rootReducer = combineReducers({ dashboard: dashboardReducer, user: userReducer }); export type RootState = ReturnType<typeof rootReducer>
  1. Proporcione el tipo RootState al objeto de estado.
 let userData = useSelector((state: RootState) => { return state.user.data; });
over 4 years ago · Santiago Trujillo Denunciar

0

Para mí, una mejor solución que especificar el estado en useSelector sería la siguiente.
Al igual que en node_modules/@types/react-redux/index.d.ts , puede usar el aumento de módulos.

 /** * This interface can be augmented by users to add default types for the root state when * using `react-redux`. * Use module augmentation to append your own type definition in a your_custom_type.d.ts file. * https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation */ // tslint:disable-next-line:no-empty-interface export interface DefaultRootState {}

Haz lo siguiente

  1. Exportar AppState en reducer src/reducer/index.ts
 const reducers = combineReducers({ userReducer, }); export type AppState = ReturnType<typeof reducers>;
  1. Crear nuevo your_custom_type.d.ts . (Prefiero reaccionar-redux.d.ts).
    En src/@types/your_custom_type.d.ts
 import 'react-redux'; import { AppState } from '../reducers'; declare module 'react-redux' { interface DefaultRootState extends AppState { }; }
  1. Agregue typeRoots en tsconfig.json
 { "compilerOptions": { ... "typeRoots": ["src/@types"] } }

Puede usar como se muestra a continuación sin especificar AppState

 import React, { memo } from 'react'; import { useSelector } from 'react-redux'; export default memo(() => { const isLoggedIn = useSelector( ({ userReducer }) => userReducer.isLoggedIn ); return <div>{isLoggedIn}</div>; });
over 4 years ago · Santiago Trujillo Denunciar

0

Si está utilizando react-redux, otra solución lista para usar sería usar RootStateOrAny .

 import { RootStateOrAny, useSelector } from 'react-redux'; // and then use it like so in your component ... const authState = useSelector((state: RootStateOrAny) => state.auth); ...
over 4 years ago · Santiago Trujillo Denunciar

0

Estos son artículos útiles.

  1. https://redux.js.org/recipes/usage-with-typescript#define-root-state-and-dispatch-types
  2. https://redux.js.org/recipes/usage-with-typescript#define-typed-hooks

Así que primero defina RootState y AppDispatch como sigue:

 //at store/index.ts const rootReducer = combineReducers({ tsReducer: tsReducer }); const store = createStore(rootReducer) export type RootState = ReturnType<typeof store.getState> export type AppDispatch = typeof store.dispatch

Y luego definir ganchos ( useAppDispatch , useAppSelector ) que se pueden usar en componentes.

 //at store/hooks.ts import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux' import type { RootState, AppDispatch } from './' export const useAppDispatch = () => useDispatch<AppDispatch>() export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

Y utilícelo en un componente como el siguiente:

 import {useAppSelector} from '../store/hooks' //... const TsApp = (): JSX.Element => { const dispatch = useDispatch(); // ERROR should be fixed const isDialogOpen = useAppSelector(state => state.tsReducer.isDialogOpen); };
over 4 years ago · Santiago Trujillo Denunciar

0

se trata solo de los tipos que necesita para satisfacer este gancho, useSelector acepta el tipo DefaultRootState , puede anular sus tipos predeterminados a través de este

 type User = { firstname: string; lastname: string; }; type SelectorTypes = { users: User[]; //...other reducers }; const router = useSelector<SelectorTypes>((state) => state.users);
over 4 years ago · Santiago Trujillo Denunciar

0

esto funcionó para mí

 import { RootStateOrAny, useSelector } from "react-redux" const search = useSelector((state: RootStateOrAny) => state.searchObj.value)
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda