Home > Back-end >  Element implicitly has an 'any' type because expression of type 'string' can
Element implicitly has an 'any' type because expression of type 'string' can

Time:08-27

I want to manage closing a modal by click not only button and also to substrate. In JSX without Typescript this code works good. This example returns to me couple errors in line:
if (universalRegExp.test(String(appointment[key])))

  1. Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ customer: string; doctor: string; complaint: string; }'.
  2. No index signature with a parameter of type 'string' was found on type '{ customer: string; doctor: string; complaint: string; }'.

What I do wrong?
Thanks.

ModalEdit.tsx

interface ModalEditI {
  id: string;
  setList: () => void;
}

const ModalEdit: FC<ModalEditI> = ({ id, setList }) => {
  const store = useContext(Context);
  const universalRegExp = /^[а-яА-Яa-zA-Z\s.]{2,30}$/;
  const date = store.stateFields.date;
  const { customer, doctor, complaint } = store.stateFields;
  const [appointment, setAppoint] = useState({
    customer,
    doctor,
    complaint
  });

  const confirmHandler = async (id: string) => {
    let counter = 0;
    for (const key in appointment) {
      if (universalRegExp.test(String(appointment[key]))) { // <--There is problem
        counter  ;
      }

      if (counter === 3) {
        editAppoint(id);
        store.setTypeOfTask('');
      }
    }
    if (counter !== 3) {
      store.snackHolder('wrong simbols');
    }
  };

  const editAppoint = async (id: string) => {
    await store.editAppoint(id, appointment, date);
    const appointments = await store.getAppointments();
    setList(appointments);
  };

  const cancelHandler = (e) => {
    if (e.target.dataset.close === 'closeThis') {
      store.setTypeOfTask('');
    }
  };

  return (
    <div 
      className='modal_substrate'
      data-close='closeThis'
      onClick={cancelHandler}
    >
      <div className='modal bigger'>
        <div className='modal_header'>
          <h1 className='modal_head_text'>Edit count</h1>
        </div>
          <button data-close='closeThis' onClick={cancelHandler}>
            Отмена
          </button>
          <button onClick={() => confirmHandler(id)}>Confirm</button>
      </div>
    </div>
  );
};

CodePudding user response:

The issue is that typescript isn't very "sure" that the key variable is a valid key of appointment.
Here is a blogpost that covers this exact situation:
https://trungk18.com/experience/how-to-iterate-over-objects-in-typescript/

In it there are a few options to solve your issue, but if you want to keep the structure of your for in loop, a the solution it proposes is to declare key beforehand with the valid type keyof typeof appointment,
so the start of your confirm handler would look a little more like this:

let counter = 0;
let key: keyof typeof appointment;
for (key in appointment) {
  if (universalRegExp.test(String(appointment[key]))) {
    counter  ;
  }
...
}
  • Related