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])))
- Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ customer: string; doctor: string; complaint: string; }'.
- 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 ;
}
...
}