[TS - Error Handling] JS → TS 마이그레이션 중 맞닥뜨린 error 모음.zip🤐

Beanxx·2022년 11월 8일
2

Error-Handling

목록 보기
4/7
post-thumbnail

JS -> TS 마이그레이션 중 맞닥뜨린 에러들을 기록합니다.

💡1️⃣ children type error

기존 코드는 아래와 같았다. children은 내장 프로퍼티가 따로 타입 지정을 안해줘도 된다고 알고 있었는데 계속 children 부분에서 에러가 발생했다..😭

const TodosContextProvider: React.FC = (props) => {
	...
  return (
    <TodosContext.Provider value={contextValue}>
      {props.children}
    </TodosContext.Provider>
  );
};

찾아보니까 React 18 버전부터 변경된 부분이 생겼고, 이 중에 chidren도 타입을 지정해줘야 한다는 것이다. 아래 코드처럼 chidren type을 따로 지정해주면 error 사라짐!

🔗 [참고자료] 리액트 18의 타입스크립트 타입 변경점

// React version 18부턴 children 사용시에 따로 타입을 지정해줘야 한다.
// 안해주면 error 발생
type Props = {
  children: React.ReactNode;
};

const TodosContextProvider: React.FC<Props> = ({ children }) => {
	...
  return (
    <TodosContext.Provider value={contextValue}>
      {children}
    </TodosContext.Provider>
  );
};


💡2️⃣ Cannot find module '~'

이미지를 import하는 코드에서 발생했던 오류!

types라는 폴더를 생성하고, 그 안에 image.d.ts 파일을 추가해줬다.
이 후에 tsconfig.json 파일에도 typeRoots 속성을 추가해줬다.
이 파일에서 사용하고자 하는 확장자명을 선언해주는 느낌?

// types/image.d.ts
declare module '*.png';
// tsconfig.json
{
  "compilerOptions": {
    "typeRoots" : ["node_modules/@types", "src/types"]
  }
}


💡3️⃣ useSelector state type error

useSelector 사용시 state에 대해 'state' is of type 'unknown'라는 에러가 발생했는데 state 타입을 어떻게 지정해줘야 할지 감이 안 잡혔다가 구글링해서 방법을 찾았다.

reducers 폴더의 index.js 파일에서 아래줄에 rootReducer에 대해 타입을 지정해준 후 export를 따로 또 해준 후에,
이를 import해서 state 타입에 지정해주면 된다.

// reducers/index.js
...
export type RootState = ReturnType<typeof rootReducer>
useSelector((state: RootState) => state.loginReducer.nickName);


💡4️⃣ No overload matches this call.

해당 호출과 일치하는 overload가 없다? 라는 의미의 에러같다.
이 에러에 해당하는 경우는 다양한 것 같은데 그 중 내 경우엔 호출하는 매개변수의 개수가 달라서 나는 오류였다.
예를 들어서 Button 컴포넌트에서 여러 버튼들을 export하도록 구현해놨는데 props로 받아오는 값들 중 어느 버튼에선 height, width만 받아오고, background 값은 안 받아오는 경우도 있었다.
즉, 지정한 interface에서 모든 값들을 사용하지 않으니까 나는 것 같았다.

interface에 타입을 지정해준 값들을 모두 사용하지 않아도 되도록 옵셔널 연산자(?)를 걸어주었다.

interface Props {
  width?: string,
  height?: string,
  background?: string
}


💡5️⃣ Cannot invoke an object which is possibly ‘undefined’

undefined 객체를 호출할 수 없다는 에러..
다른 파일에서 계속 에러가 나는 부분들이 있어서 어쩔 수 없이 props로 받아온 값들 중 옵셔널 연산자(?)를 사용해서 처리를 해줬는데 이것땜에 이 오류가 새롭게 등장해버렸다,,

에러 메세지를 구글링해보니까 옵셔널 연산자를 삭제할 수 있으면 하라는데 나같은 경우는 이걸 삭제해버리면 다른 파일에서 더 많은 오류가 나서 삭제할 수가 없었다,,
그래서 찾은 방법이 undefined일 때는 함수가 실행되지 않도록 처리를 해주라는 것이었다!
🧙‍♂️ 삼항연산자나 if문으로 true일 때 즉, 값이 있을 때 함수를 실행하도록 조건문을 걸어줬더니 에러가 사라졌다.

interface Props {
  ...
  setOnOff?: (onOff: string) => void;
}

// props.setDevType(e.target.value); ← 기존 코드
props.setDevType && props.setDevType(e.target.value); // ← here!!


💡6️⃣ Property '~' does not exist ...

💫 Property 'value' does not exist on type ~.

fontawesome 아이콘에 value={search} 요런 식으로 value를 선언해줘야해서 value 속성을 넣었는데 이 속성 자체가 아이콘 i태그에 존재하지 않는 속성이여서 나는 에러같다.

아래 블로그를 참고해서 value property를 아예 추가해준 후, 타입까지 지정해줬다.
🔗 블로그 참고 자료

declare module 'react' {
  interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
    value?: string;
  }
}

💫 Property ‘user’ does not exist on type ‘MultiFactorUser’.

221119
전에도 비슷한 에러가 발생한 적이 있어서 그때 해결했던 방법대로 declare module~ 해서 해결하려고 했는데 에러가 사라지지 않았다,,
구글링해도 firebase 내에 있는 mutiFactor에 대한 해결 방법을 명확하게 찾을 수 없어서 해결방안을 찾는데 시간을 많이 소비해버렸다.

이 해결방안이 맞는지는 모르겠지만 이 에러를 해결하려는 과정에서 시간을 넘 많이 잡아먹어서 일단 multiFactor 위에 커서를 올리면 등장하는 문구 중에 저 파란 문구들을 클릭하면 이에 대한 index.d.ts 파일로 넘어가게 되는데 여기서 interface MultiFactorUser 부분에 user에 대한 타입을 지정해줬더니 에러는 사라졌다..!


💫 Property ‘value’ does not exist on type ‘EventTarget’

EventTarget에 value라는 속성이 존재하지 않는다는 에러!

setEmail((e.target as HTMLInputElement).value) 이렇게 e.target에 대한 부분 타입을 지정해서 해결!

onChange={(e) => setEmail((e.target as HTMLInputElement).value)}


💡7️⃣ Type 'string[]' is not assignable to type 'string'

<li key={idx} style={{ background: pick(el) }}> 이 코드에서 background 쪽에서 에러가 발생했다. pick() 함수로 받아오는 값이 ['#DD0031'] 요런 식으로 문자열이 원소인 배열(string[]) 형태인데 background 값으로는 string이 와야해서 서로 타입이 맞지 않아 발생한 에러같다.

pick() 함수쪽에서 반환 형태를 배열이 아닌 문자열 형태로 수정을 해줬다.

const pick = (item: string) => {
  return stackBackgrounds
    .filter((el) => el.stack === item)
    .map((el) => el.color)[0]; // ← [0]으로 배열이 아닌 문자열이 반환되도록 수정!
};
profile
FE developer

0개의 댓글