iamkanguk.dev

[맵필로그] Strict Mode 설정 + 발생한 이슈 + tsconfig.json 일부 분석 본문

사이드 프로젝트/맵필로그

[맵필로그] Strict Mode 설정 + 발생한 이슈 + tsconfig.json 일부 분석

iamkanguk 2024. 1. 22. 19:03

이제 express가 아니라 NestJS를 하면서 자연스럽게 TS와 친해지려고 노력하고 있다. 최근에 Nest로 프로젝트를 하면서 tsconfig.json 파일을 만질 때가 있었는데, 정확히 이 파일이 어떤 역할을 하는지 모르고 사용을 했던 것 같다.

 

그리고 프로젝트를 하는 도중에 내가 작성한 소스를 한번 쭉 그냥 보고 있었는데 최대한 any 타입을 지양하고 각종 메서드나 변수 등에 타입을 꼭 달아주었다. 그런데도 몇 군데 빼먹은 곳이 있었는데 생각해보니까 얼핏 이런걸 에러로 보여주는 기능이 있는데? 라고 알고 있었는데 적용이 안되어서 내가 실수한 부분이 몇 군데 있구나 싶었다.

 

보니까 strict 모드가 활성화 되어있지 않은 것. 그래서 이번 포스팅에서는 strict mode를 어떻게 활성화 했는지 (아주간단), strict mode를 키면서 에러 난거 하나 설명하기, 마지막으로 tsconfig.json 파일을 간단하게? 옵션 설명을 하는 글을 적어보려고 한다.

 

1.  Strict 모드 활성화 (strict: true)

Strict 모드는 tsconfig.json 파일에서 설정할 수 있다. Strict 모드는 모든 엄격한 유형 검사 옵션을 의미하는데 이 옵션을 사용하지 않는 것은 TS를 쓰지 않는 것이라고 할 수 있다. (왜 지금까지 안쓰고 있었을까...!)

 

{
  "compilerOptions": {
     "strict": true
  }
}

 

이 strict만 true로 설정하면 strict mode family 프로퍼티들이 전부 true로 설정된다. 하지만.. 안그래도 지금 이거 strict를 true로 설정하니까 각종 빨간줄이 엄청 많이 나오는데.. 하나씩 해결하기 넘 귀찮다...

 

만약에 이런 빨간줄이 귀찮다 ==> 선택적으로 몇 개는 false로 설정하면 될 것 같다.

 

  1. alwaysStrict --> 엄격모드에서 구문 분석 후 각 소스 파일에 "use strict" 코드 삽입
  2. strictNullChecks --> null 및 undefined 값에 대한 유형을 조정하는 옵션
  3. strictBindCallApply --> bind, call, apply 사용할 때 더욱 엄격하게 검사하는 옵션
  4. strictFunctionTypes --> 엄격한 함수 유형검사 사용
  5. strictPropertyInitialization --> 정의되지 않은 클래스의 속성이 생성자에서 초기화되었는지 확인하는 옵션
  6. noImplictAny --> 명시적이지 않은 any 타입이 지정될 경우 에러 발생
  7. noImplictThis --> 암시적 any 유형이 있는 this 표현식에서 오류 발생

위 7개가 프로퍼티들이다. 각 옵션에 대해서 설명은 다른 블로그를 통해 확인하시면 좋을 것 같다!

 

2.  Strict mode를 적용하면서 발생한 이슈 하나 공유!

has no initializer and is not definitely assigned in the constructor

 

타입 선언 후 초기값을 설정하지 않아서 생긴 문제이다. 이 문제는 어떻게 해결할 수 있을까?

 

  • strictPropertyInitialization을 false로 설정한다.
  • 확정 할당 어선셜 연산자 사용 -> !와 ?는 TypeScript에서 확정 할당 어선셜이라고 부른다. !는 컴파일러에게 선언은 하지 않았지만 무조건 값이 있다고 생각하자 라는 뜻이다. 그리고 ?는 필수가 아닌 속성이라고 알려주는 것이다.
  • 초기값 선언하기

 

3.  tsconfig.json 일부 분석

내가 궁금했던 옵션들 + 자주 적용한다는 옵션 위주로 간단하게 설명을 해보려고 한다. 두고두고 까먹을때마다 보려고 하니 참고해주길!

(1) skipLibCheck

선언 파일 유형 검사를 스킵할지에 대한 여부를 설정할 수 있는 옵션이다. 당연히 타입스크립트를 쓰니까 체킹을 해야하지 않아? 라고 생각할 수 있지만 만약에 프로젝트 규모가 크다면 상당한 시간이 소모될 수 있다. 그래서 이 옵션을 true로 설정하여 파일 타입 체크를 생략해서 컴파일 시간을 줄여줄 수 있다.

(2) declaration

이 옵션을 true로 설정하면 TS 파일을 JS 파일로 컴파일하는 과정에서 JS파일과 함께 d.ts 파일이 생성되게 한다.

보통 객체랑 함수를 쓰다보면 타입을 커스텀하는 경우가 생길텐데 이 때 타입들을 ts파일에 넣어도 되지만 용도가 다르기 때문에 분리하는 것이 좋다. 이럴 때 d.ts 파일을 만들어서 따로 타입만 관리하는데 사용되는 옵션이다.

(3) removeComments

컴파일 시 타입스크립트 소스의 주석을 모두 제거하는 것을 설정하는 옵션이다.

(4) experimentalDecorators / emitDecoratorMetadata

타입스크립트의 @Decorator를 사용하기 위해서는 true로 적용해야 작동한다.

(5) forceConsistentCasingInFileNames

파일의 이름을 대소문자 판별하게 하는 옵션이다. 프로그래밍 세계에서는 같은 알파벳이라도 대소문자를 모두 구분하기 때문에 가능한 true로 설정해서 사용하는 것이 좋다.

(6) resolveJsonModule

확장자가 .json인 모듈의 import를 허용하는 설정이다. 예를 들어 { name: "홍길동" } 이라는 JSON 데이터가 저장된 test.json이 있다고 가정해보자. TS파일에서 " import settings from './test.json'; " 으로 import를 하려고 하면 에러가 발생한다. 이 때 이 옵션을 true로 설정하게 되면 import가 가능해진다.

(7) sourceMap

컴파일 된 파일 디렉터리에 .js.map 파일이 만들어진다. 이 파일은 변환된 js 코드가 ts의 어디에 해당하는지 알려준다. 보통 디버깅에서 많이 사용한다고 한다.

 

실제로 타입스크립트 프로젝트를 배포하고 브라우저에서 개발자 모드를 이용해서 source 탭에서 보면 브라우저는 js만 인식하지만 매핑 파일에 의해 ts 파일을 인식하는 것을 볼 수 있다고 한다.

(8) noFallthroughCasesInSwitch

switch 문이 이상하면 에러를 내주는 옵션이다. 예를 들어서 switch 문에서 비어있지 않은 case라면 반드시 break 또는 return으로 case를 종료시키도록 에러를 내준다. 우리는 이를 통해서 의도치 않은 false through case에 의한 버그를 예방할 수 있다.

(9) baseUrl / paths

import 구문의 모듈 해석 시에 기준이 되는 경로를 지정한다.

노드 패키지는 따로 경로 없이 import를 하고 직접 만든 소스파일은 경로를 적어준다. 참고로 노드 패키지는 node_modules가 보통 프로젝트 최상단 경로에 있기 때문에 자동으로 인식을 해줘서 따로 경로를 적지 않아도 된다.

 

보통 상대경로로 import를 하는데 만약에 다른 경로에 파일을 만들어서 동일한 모듈을 import 하려고 한다면 위치 기준점이 달라져서 번거로울 수 있다. 그래서 우리는 baseUrl과 path 속성을 통해 절대경로로 import 한다.

 

baseUrl 속성에는 기본 경로로 설정해주고 아래에 paths 속성에 대해 절대경로를 지정하고 싶은 경로들을 지정해주면 된다.

{
  "compilerOptions": {
    "baseUrl": "./", // 절대 경로 모듈이 아닌, 모듈이 기본적으로 위치한 디렉토리 설정
    "paths": { // 'baseUrl'을 기준으로 상대 위치로 가져오기를 다시 매핑하는 항목 설정
      "@components/*": [
        "src/components/*" // import {} from '@components/파일' 할때 어느 경로로 찾아들어갈지 paths 설정
      ],
      "@utils/*": [
        "src/utils/*"
      ],
    },
    "outDir": "./dist", // 컴파일할때 js 파일 위치 경로 지정
  },
}

 

하지만 ts-node를 통해 소스파일을 실행하면 오류가 난다. 이유는 tsconfig.json 설정은 경로 alias만 준거지 실제 경로를 바꾼게 아니다. 그래서 tsconfig-paths와 tsc-alias 라는 모듈을 설치해야 한다.

(10) include

프로젝트에서 컴파일할 파일들을 지정하는 속성이다. 보통 와일드카드 패턴으로 지정을 해준다.

  • *: 해당 디렉토리에 있는 모든 파일
  • ?: 해당 디렉토리에 있는 파일들의 이름 중 한 글자라도 포함하면 해당
  • **: 해당 디렉토리의 하위 디렉토리의 모든 파일을 포함

참고자료

- https://velog.io/@gingaminga/%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0-has-no-initializer-and-is-not-definitely-assigned-in-the-constructor

 

has no initializer and is not definitely assigned in the constructor

Typescript가 나를 괴롭히는구나..!

velog.io

- https://inpa.tistory.com/entry/TS-%F0%9F%93%98-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-tsconfigjson-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0-%EC%B4%9D%EC%A0%95%EB%A6%AC#alwaysstrict

 

📘 타입스크립트 컴파일 설정 - tsconfig 옵션 총정리

타입스크립트 컴파일 설정 tsconfig.json은 타입스크립트를 자바스크립트로 변환 시키는 컴파일 설정을 한꺼번에 정의 해놓는 파일이라고 보면 된다. 프로젝트를 컴파일 하는데 필요한 루트 파일,

inpa.tistory.com