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.
function ValidationErrors( {errors}: Errors ) {should befunction ValidationErrors( {errors}: { errors: Errors}) {(you applied the Errors interface topropsinstead ofprops.errors, I'll also recommend to name the interfaceIErrors)