1

I have a website that uses React, React-redux, now I am converting it into Typescript, but I can't. I have this:

Login.tsx

....
import ValidationErrors from 'components/ValidationErrors'
import { useAppDispatch, useAppSelector } from 'store/hooks';

function Login() {
    
    ...
    ...
    const errors = useAppSelector(state =>state.error) 

    return (        
        <div className="login">                     
           ....
            { errors.errors.length &&                                             
                <ValidationErrors errors={errors} />                    
            }
         ...
         </div>
      )
}
   

components/ValidationErrors.tsx

    import React from 'react';
    import Errors from 'interfaces/Errors';
    
    function ValidationErrors( {errors}: Errors ) {            
        return (                
            <div>
                <div className="font-medium text-red-600">{errors.message}</div>                
                <ul className="mt-3 list-disc list-inside text-sm text-red-600">
                    {Object.keys(errors.errors).map(function (key, index) {                        
                        return <li key={index}>{errors.errors[key]}</li>;
                    })}
                </ul>
            </div>        
        );
    }

export default ValidationErrors

interfaces/Errors.ts

export default interface Errors {
    message:string | null,
    errors: {
        [key:string]:string[]        
    }
}

This is the json format that backend send when there is an error:

{ "message":"The given data was invalid.", "errors": { "email": ["These credentials do not match our records."] } }

I get 2 typescript errors:

{Object.keys(errors.errors).map(function (key, index) {
return {errors.errors[key]}; })}

(parameter) key: string Element implicitly has an 'any' type because index expression is not of type 'number'.ts(7015)

and here:

<ValidationErrors errors={errors} />

(property) Errors.errors: { [key: string]: string[]; } Type 'Errors' is not assignable to type '{ [key: string]: string[]; }'. Index signature for type 'string' is missing in type 'Errors'.ts(2322) Errors.ts(3, 5): The expected type comes from property 'errors' which is declared here on type 'IntrinsicAttributes & Errors'

This is the error reducer: store/reducers/errorReducer.ts

import Errors from 'interfaces/Errors'
import {Action, ActionType} from 'store/types'

const initialState: Errors = {
    message: null,
    errors: {
        '':['']
    }   
}

export const errorReducer = (state : Errors = initialState, action: Action): Errors =>{
    switch(action.type){
        case ActionType.SET_ERROR:          
            return {
                message: action.payload.message,
                errors: action.payload.errors
            }                   
        default:
            return state
    }
} 

and this my global reducer: store/reducers/index.ts

import {combineReducers} from 'redux'
...
...
import {errorReducer} from './errorReducer'


const rootReducer = combineReducers({
    .....
    error: errorReducer
})

export type RootState = ReturnType<typeof rootReducer>;
export default rootReducer;

And this is my store: store/store.ts

import { configureStore, ThunkAction, Action } from '@reduxjs/toolkit';
import reducer from './reducers'

export const store = configureStore({
    reducer
});

export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;
export type AppThunk<ReturnType = void> = ThunkAction<
  ReturnType,
  RootState,
  unknown,
  Action<string>
>;

What am I doing wrong? thanks.

3
  • 1
    afaik function ValidationErrors( {errors}: Errors ) { should be function ValidationErrors( {errors}: { errors: Errors}) { (you applied the Errors interface to props instead of props.errors, I'll also recommend to name the interface IErrors) Commented Apr 21, 2022 at 20:34
  • 1
    You are destructuring errors object from the error response so you need to use another type, or you do not destructure and say ( errorResponse: Errors ) { const { errors } = errorResponse } Commented Apr 21, 2022 at 20:38
  • Thanks dudes, now it is working, but you mentioned that I applied the Errors interface to props, that seems to be true because it is working now, but I thought that I should only destructure the props, not the interface, that's why I did this {errors}, it is still confusing Commented Apr 21, 2022 at 23:35

1 Answer 1

0

I think there are 2 ways to fix this,

  1. Don't destructure the function's parameters and refer to Errors interface

    function ValidationErrors(errors: Errors) {
    
    }
    
  2. Provide information about each value that you will get on destructuring parameters.

    function ValidationErrors({ message, errors }: { message: string | null, 
    errors: { [key: string]: string[] } }) {
    
    }
    
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.