[Type Script] 타입 단언( type assertion)의 중요한 예시

Hwanhoon KIM·2023년 7월 30일
0

처음에 이론으로만 배우다가 역시 막상 코드를 사용하려고 하니까 타입단언을 안 쓰면 안되는 구간이 생겼고, 타입 단언을 사용해줘야함을 알게 되었다.
(! 결론 꼭 보기)


상황

reduxtodo liststore에 저장해서 쓰는 상황이고, 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 부분에 다음의 에러가 발생한다.

error msg

해결

이는 처음에 initialState가 빈 배열[]이라서 타입을 Partial로 지정했기 때문인데, 이를 해결하기위해서 위 함수에서 타입 단언을 사용해 일시적으로 삭제하기 함수 스코프 안에서의 storedTodoList의 타입을 변경해주는 작업이 필요하단 것을 알게되었다.

그리고 다음과 같이 작성하면 된다.

...
const filteredTodo: T_todoState = (storedTodoList as T_todo[]).filter(
      (el) => el.id !== id
    );
...

그럼 잘 작동되는 것을 확인할 수 있다.

결론

사실 애초에 이렇게 할 필요들이 없다는 것을 깨닳았다. 타입스크립트에서 배열로 타입지정하고, 그 안에 요소들의 타입을 지정하더라도 빈배열도 허용하기 때문이다..! 사실 위에 문제에서는 저렇게 해결할 필요가 전혀 없었다! 하지만 타입단언 사용 예시로는 남겨두면 나쁘지 않을 것 같아서 다음 결론을 추가하고 마무리한다.

profile
Fullstack Developer, I post about HTML, CSS(SASS, LESS), JavaScript, React, Next, TypeScript.

0개의 댓글