처음에 이론으로만 배우다가 역시 막상 코드를 사용하려고 하니까 타입단언을 안 쓰면 안되는 구간이 생겼고, 타입 단언을 사용해줘야함을 알게 되었다.
(! 결론 꼭 보기)
redux
로 todo list
를 store
에 저장해서 쓰는 상황이고, todo
를 삭제하는 함수 로직에 문제가 발생한다.
todo 모듈에서 다음과 같이 타입을 정의했다.
redux/modules/todo.ts
import { PayloadAction, createSlice } from '@reduxjs/toolkit';
export interface T_todo {
id: number;
todo: string;
}
export type T_todoState = Partial<Array<T_todo>>;
const initialState: T_todoState = [];
const todoSlice = createSlice({
name: 'Todo Slice',
initialState,
reducers: {
postTodo: (state: T_todoState, action: PayloadAction<T_todo>) => {
console.log(action.payload);
return [...state, action.payload];
},
},
});
export default todoSlice;
export const { postTodo } = todoSlice.actions;
봐야할 부분은 export type T_todoState = Partial<Array<T_todo>>;
이다.
initialState
에서 빈 값을 갖기 때문에 어쩔 수 없이 Partial
로 정의했지만 이것이 나중에 todo
삭제 함수의 로직에 방해가 되었다.
다음과 같다.
components/Main/DisplayTodo/TodoList.tsx
const TodoList: React.FC<{}> = () => {
...
const storedTodoList: T_todoState = useAppSelector((state) => state.todoList);
const dispatch = useAppDispatch();
...
// 삭제 하기
useEffect((): void => {
if (
!confirmToDelete ||
deleteModalToggler === null ||
storedTodoList === null
) {
return;
}
const id = deleteModalToggler[1];
// filteredTodoDB = 해당 todo 값만 뺀 전체 todoDB
const filteredTodo: T_todoState = storedTodoList.filter(
(el) => el.id !== id
);
dispatch(filteredTodo);
setDeleteModalToggler(null);
setConfirmToDelete(false);
}, [confirmToDelete]);
여기서 봐야할 부분은 storedTodoList.filter()
부분이다.
처음에 정의할 때 Partial
로 정의했기 때문에 위와 같이 코드를 쓰면 el
부분에 다음의 에러가 발생한다.
이는 처음에 initialState
가 빈 배열[]
이라서 타입을 Partial
로 지정했기 때문인데, 이를 해결하기위해서 위 함수에서 타입 단언을 사용해 일시적으로 삭제하기 함수 스코프 안에서의 storedTodoList
의 타입을 변경해주는 작업이 필요하단 것을 알게되었다.
그리고 다음과 같이 작성하면 된다.
...
const filteredTodo: T_todoState = (storedTodoList as T_todo[]).filter(
(el) => el.id !== id
);
...
그럼 잘 작동되는 것을 확인할 수 있다.
사실 애초에 이렇게 할 필요들이 없다는 것을 깨닳았다. 타입스크립트에서 배열로 타입지정하고, 그 안에 요소들의 타입을 지정하더라도 빈배열도 허용하기 때문이다..! 사실 위에 문제에서는 저렇게 해결할 필요가 전혀 없었다! 하지만 타입단언 사용 예시로는 남겨두면 나쁘지 않을 것 같아서 다음 결론을 추가하고 마무리한다.