Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type 'undefined' must have a '[Symbol.iterator]()' method that returns an iterator

I am trying to convert my reducer from JS to typescript but I am getting a weird error that I have not been able to resolve. The error comes from using ellipsis for array deconstruction in the reducer [...state.messages]. Basically the code is as follows: Reducer:

import { HomeScreenAction } from '../actions';
import { HomeState, User, Message } from '../types';
import * as constants from '../constants';
import { combineReducers } from 'redux';

export function userState(state: HomeState = {}, action: 
HomeScreenAction): HomeState {
switch (action.type) {
case constants.REQUEST_USER:
case constants.RECEIVE_USER:
  return { user: action.user };
default:
  return state;
}
}


export function messagesState(state: HomeState = {}, action: 
HomeScreenAction):HomeState {
switch (action.type) {
case constants.REQUEST_MESSAGES:
case constants.RECEIVE_MESSAGES:
  return { messages: action.messages };
case constants.Test1:
  return{ ...state, user: action.payload};
case constants.Test2:
  return {...state, messages:[ ...state.messages, action.payload ]};
default:
  return state;
}
}

const rootReducer = combineReducers({
userState,
messagesState
});

export default rootReducer;

types:

export interface HomeState {
user?: User;
messages?: Message[];
}
export interface Test1 {
type: typeof constants.Test1
payload: User
}

export interface Test2 {
type: typeof constants.Test2
payload: Message
}

and the tsconfig.js:

  "compilerOptions": {
/* Basic Options */
"target": "es6",                          
"watch": false,
"module": "commonjs",
 "lib":  [ "dom", "es6", "es2015" , "dom.iterable"],
// "allowJs": true,
// "checkJs": true,
"jsx": "react",
// "declaration": true,
"sourceMap": true,
// "outFile": "./",
"outDir": "./lib",

"strict": true

},
"include": ["./src/"]
}

I have tried different libs such as es2015 and es5 but still I get an error for

[...state.messages]

any help would be very much appreciated.

like image 935
BlackLog Avatar asked Sep 14 '25 17:09

BlackLog


1 Answers

Since messages is an optional property in HomeState, messages can be undefined in which case there would a runtime error in array destructuring.

To protect from a runtime error, TS is throwing a compile time error.

The easiest way to resolve this would be to check if state.messages is empty and initialise with an empty array. Example:

 case constants.Test2:
   let messages: Message[] = state.mesaage || [];
   return {...state, messages:[ ...messages, action.payload ]};
like image 86
dRoyson Avatar answered Sep 16 '25 18:09

dRoyson