setToDos((oldToDos) => {
const targetIndex = oldToDos.findIndex((toDo) => toDo.id === id);
//const oldToDo = oldToDos[targetIndex];
const newToDo = { text, id, category: name };
return [
...oldToDos.slice(0, targetIndex),
newToDo,
...oldToDos.slice(targetIndex + 1),
];
});
기존에 작성한 todoList에서 기존 목록의 순서를 그대로 유지하고 category 속성만 바꾸는 로직을 만드는 중 oldToDos에 오류가 발생한다.
(parameter) oldToDos: IToDo[]
setToDos((oldToDos) => {
const targetIndex = oldToDos.findIndex((toDo) => toDo.id === id);
//const oldToDo = oldToDos[targetIndex];
const newToDo = { text, id, category: name };
return [
...oldToDos.slice(0, targetIndex),
newToDo,
...oldToDos.slice(targetIndex + 1),
];
Argument of type '(oldToDos: IToDo[]) => { text: string; id: number; category: string; }[]' is not assignable to parameter of type 'IToDo[] | ((currVal: IToDo[]) => IToDo[])'.
Type '(oldToDos: IToDo[]) => { text: string; id: number; category: string; }[]' is not assignable to type '(currVal: IToDo[]) => IToDo[]'.
Type '{ text: string; id: number; category: string; }[]' is not assignable to type 'IToDo[]'.
Type '{ text: string; id: number; category: string; }' is not assignable to type 'IToDo'.
Types of property 'category' are incompatible.
Type 'string' is not assignable to type '"TO_DO" | "DOING" | "DONE"'.ts(2345)
No quick fixes available
강의에서는
const newToDo = { text, id, category: name };
any 속성을 추가해서 해결했다.
const newToDo = { text, id, category: name as any};
{ text: string; id: number; category: string; }가 IToDo 타입에 맞지 않는다는건데 그 이유는
export interface IToDo {
text: string;
id: number;
category: 'TO_DO' | 'DOING' | 'DONE';
}
category가 'TO_DO' | 'DOING' | 'DONE' 속성을 가지고 있기 때문인것으로 보인다.
그래서 as any 로 속성을 강제로 바꿔줘서 오류를 없앴다.
any는 TS의 탈출구문으로 타입 시스템의 제한을 벗어나고 싶을때 any 를 사용할 수 있다.
any를 사용하면 타입의 안정성을 희생하는 대신 코드를 원래 JS에 더욱 가깝게 작성할 수 있다.
any는 어떤 타입이든 다른 타입에 할당할 수 있도록 만드는 '타입 와일드카드'와 같다.
https://www.typescriptlang.org/ko/play#example/any
JS와 달리 변수의 타입을 정해서 지나치게 자유로운 JS에 적절한 제한을 둬서 생기는 오류로 보인다. TS에 발을 담궈보니 더 궁금해져서 앞으로도 TS를 공부해보고싶다.