TypeError: Cannot read properties of undefined (reading 'value')
Javascript로 개발하다 보면 위와 같은 메시지를 자주 보게 될 것이다.
주된 이유는 모듈을 import 하지 않고 사용했거나, 변수를 선언하지 않고 사용한 경우가 대부분이다.
그렇다면 이런 문제들을 Runtime이 아니라, 코드 작성 시점에 미리 알 수 있는 방법은 없을까?
장기적인 해결책
장기적인 관점에서 추천하는 방법은 Typescript로 전환하는 것이다.
이런 문제점을 해결할 수 있을 뿐만 아니라 데이터 타입 지정, Generic 사용 등 여러가지 장점이 있다.
단기적인 해결책
이미 프로젝트가 Javascript로 작성되어 있고, 팀원 전체가 Typescript에 대한 지식이 전무한 경우에는 당장 Typescript로 전환하는 것은 현실적인 해결책이 아니다.
대신 Javascript를 Typescript스럽게 사용할 수 있는 방법이 있다.
프로젝트 루트에 jsconfig.json 파일을 생성하고 아래와 같은 내용을 작성하면 된다.
{
"compilerOptions": {
"checkJs": true
},
"exclude": ["node_modules", "**/node_modules/*"]
}
파일 내용을 간단히 설명하자면, node_modules에 있는 파일을 제외하고 모든 Javascript 파일에서 타입 체크를 하겠다는 옵션이다.
예시
아래 파일은 오류가 날 수 밖에 없는 코드이다.
// import { myModuleData } from "./my-module";
// const myObject = {
// string: 'myObject',
// number: '1234'
// }
// const string = 'rootString'
// const number = 1234;
myObject.float = 12.345
console.log(`myModuleData: ${myModuleData.string} / ${myModuleData.number}`);
console.log(`myObject: ${myObject.string} / ${myObject.number} / ${myObject.float}`);
console.log(`rootData: ${string} / ${number}`);
jsconfig.json 적용 전
코드 상에서는 전혀 오류 표시가 나오지 않는다.
실행을 해야 비로소 문제점이 발견된다.
jsconfig.json 적용 후
실행 전에 이미 코드 상에 오류를 표시해 주고 있다.
아쉬운 점
하지만 단점도 존재한다. 말 그대로 Typescript스럽게 사용하는 것이지, 직접 타입을 지정해서 사용하는 것이 아니다.
그러다 보니 암시적으로(implicitly) 추론되는 타입에 포함되지 않는 property를 사용할 때에는 오류라고 인식을 하게 된다.
이 부분도 해결책 있다. 속성에 접근할 때 콤마(.)로 접근하지 않고, 대괄호([ ])로 접근하면 된다.
// jwt 생성 시 payload에 userId를 포함시켜 생성하지만
const token = jwt.sign({ userId }, secretKey);
// jwt.verify가 반환하는 기본 타입에는 userId가 포함되어 있지 않기 때문에 오류라고 인식
const jwtDecoded = jwt.verify(userToken, secretKey);
const userId = jwtDecoded.userId; // 오류로 인식
const userId = jwtDecoded['userId']; // 문제 없음
참고
'Javascript & Typescript' 카테고리의 다른 글
Javascript로 백엔드 개발할 때 Babel을 꼭 써야 될까? (0) | 2022.10.27 |
---|---|
Prettier로 코드 포맷 통일하기 (1) | 2022.10.24 |