방구석에 놔둔 개발 노트

1년차 웹 / 앱 프론트엔드 엔지니어의 좌충우돌 얼렁뚱땅 앞뒤짱구 생존기

2023-01-16: TypeScript 학습 (6)

TypeScript 실습편, 작은 CRUD 프로젝트 만들어보기 종료.

이전 시간에 작업했던 내용을 토대로 오늘 작은 CRUD 프로젝트를 완료했다. 구현하면서 궁금하거나, 알아야했던 내용들은 어제 학습한 내용을 토대로 해결됐으며 덕분에 이후의 내용들을 만드는 데에 문제가 있진 않았다.

여기서는 간략하게 해당 프로젝트의 구현 내용 및 레포지토리를 기록하고, 오늘 작업하면서 발생한 문제 해결 한 가지를 간략하게 작성하고 마치고자 한다.

📽️ 댓글 시스템 CRUD 프로젝트 결과물

  • 이미지 데모

  • 관련 레포지토리

https://github.com/DrunkenNeoguri/ts-cra-redux-prac

❓ 추가 문제 해결 사항

1️⃣ useState의 setState의 함수 타입 선언

useState를 사용할 때, 초기값을 통해 state의 타입을 추론하여 정해지는 것을 학습을 하며 배웠으나, 경우에 따라서는 setState의 값을 하위 컴포넌트에 넘겨줘야하는 상황이 생길 수도 있다.

이 경우 이 props로 넘겨준 setState 함수의 타입을 정의해줘야 하는데, 이 타입을 어디서 가져와야할지 감이 잡히지 않을 때가 있다.

이때는 이전에 RootState의 타입 정의를 확인하려고 거슬러 올라가듯 해당 함수 또한 그런 방식으로 타입을 거슬러 올라가 확인하면 된다.

위와 같이 setState 함수에 마우스를 올리면 관련 정보를 볼 수 있는데 이렇게 타입의 정보를 알 수도 있으므로 이 방법을 적극 활용하여 타입 선언에 활용하자.

2️⃣ 타입 좁히기(type narrowing)를 통한 선택적 prop의 타입 에러 방지

CommentForm 컴포넌트의 경우, 수정 양식이나 작성 양식을 생각하면 형태가 동일할 것이라 판단하여 해당 컴포넌트를 공통적으로 쓰되 수정이냐, 작성이냐에 따라 일부 프로퍼티를 가져오거나 코드 내용이 달라지는 등의 변경 사항을 적용했다.

이 과정에서 위에 말하다시피 그냥 작성하는 경우는 따로 프로퍼티가 필요하지 않지만 이미 있는 내용을 수정할 때는 작성된 값을 가져와야 하니 별도의 프로퍼티를 가져올 필요가 있었다.

그래서 아래와 같이 선택적으로 값을 받아올 수 있도록 타입을 지정해줬다.

const CommentForm: React.FC<{
  data?: UserInputData;
  mode?: string;
  setModifyState?: Dispatch<SetStateAction<boolean>>;
}> = (props) => {
  const initialState: UserInputData = ...

이렇게 해결되겠다 싶었는데, 상위 컴포넌트에서 넘겨받은 setModifyState prop을 활용하는 내용에서 아래와 같은 문제가 발생했다.

if (props.mode === "modify") {
  dispatch(commentModify(userData));
  props.setModifyState(false);
    // 에러: '정의되지 않음'일 수 있는 개체를 호출할 수 없습니다.
} else { ...

위와 같이 개체를 호출할 수 없을 경우, 에러가 출력되는 문제가 발생하기에 이 문제를 해결하기 위해 어떻게 해야할까 고민했는데 답이 생각보다 쉽게 나왔다.

‘호출할 수 없다’는 것은 값을 못 받아오는 것이므로, 값이 있다는 건 ‘호출할 수 있다’가 되는 것이다.

이 점을 고려해서 해당 setModiftState prop이 있으면 사용할 수 있도록 하면 되는 것이다.

따라서 아래와 같이 조건문을 통한 타입 좁히기를 통해서 값이 있을 때에만 setModiftState를 사용하도록 했다.

if (props.mode === "modify") {
  dispatch(commentModify(userData));
  if (props.setModifyState !== undefined) {
    props.setModifyState(false);
  } ...

위의 방식을 통해 호출할 수 없는, 객체의 값이 없을 경우의 문제를 해결할 수 있었다.

📁 참고 자료

Dispatch > 이란?

Type Narrowing