내가 보려고 정리한 tsconfig(1)

milkboy2564·2023년 11월 6일
7
post-thumbnail

tsconfig.json이란?

tsconfig.json 파일은 프로젝트를 컴파일하는 데 필요한 루트 파일과 컴파일러 옵션을 지정합니다.

디렉터리에 tsconfig.json 파일이 있다면 해당 디렉터리다 타입스크립트 프로젝트의 루트가 됩니다. tsconfig.json에 대해 살펴보기 이전에 tsconfig.json을 사용하는 타입스크립트 컴파일러인 tsc에 대해 살펴보겠습니다.

tsc

tsc란 타입스크립트 코드를 자바스크립트 코드로 컴파일하는 타입스크립트 컴파일러입니다.

일반적으로 컴파일(compile)이란 특정 플랫폼에서 실행 가능한 형태로 변환하는 과정을 의미합니다. 자바스크립트는 브라우저에서 실행이 되기 때문에 컴파일이 필요없는 대표적인 인터프리터 언어였으나 타입스크립트가 보편화되면서 브라우저는 이해할 수 없는 타입스크립트를 자바스크립트로 변환해주는 과정이 꼭 필요하게 됐습니다.

타입스크립트 컴파일러 tsc를 사용하면 타입스크립트 코드를 자바스크립트로 변환하는 몇 가지 단계가 발생합니다.

1. tsconfig 읽기:

타입스크립트 프로젝트라면, root에 tsconifg.json을 읽는 작업부터 시작하게 됩니다.

2. preprocess:

파일의 root 부터 시작해서 imports로 연결된 가능한 모든 파일을 찾습니다.

3. 어휘 분석(토큰화):

그런 다음 타입스크립트 컴파일러는 먼저 토큰화라고도 하는 어휘 분석을 수행합니다. 소스 코드를 토큰(키워드, 식별자, 연산자 등)이라는 작은 단위로 분해하고 토큰 스트림을 생성합니다.

4. 구문 분석(파싱):

그런 다음 컴파일러는 이 토큰을 사용하여 코드의 문법 구조를 나타내는 AST(추상 구문 트리)를 생성합니다. 이 단계에서는 구문 오류를 검사하고 코드가 타입스크립트 구문 규칙에 맞는지 확인합니다.

5. 의미 분석:

타입스크립트 컴파일러는 코드의 시맨틱을 분석합니다. 여기에는 타입 검사, 심볼 해상도 및 타입스크립트 타입 시스템에 기반한 다양한 검사가 포함됩니다. 이 단계에서는 코드가 타입스크립트 언어에 지정된 타이핑 규칙을 준수하는지 확인합니다.

6. 자바스크립트로 변환:

타입스크립트 코드가 어휘, 구문, 의미 검사를 통과하면 컴파일러는 타입스크립트 코드를 자바스크립트로 트랜스파일합니다. 컴파일러는 타입스크립트 전용 구문과 유형을 그에 상응하는 자바스크립트 구조체로 변환합니다. 예를 들어 인터페이스, 데코레이터, 유형 어노테이션과 같은 타입스크립트 전용 기능을 변환하거나 제거하여 모든 자바스크립트 환경에서 실행할 수 있는 자바스크립트 코드를 생성합니다.

7. 출력 생성:

마지막으로 트랜스파일된 자바스크립트 코드가 하나 이상의 자바스크립트 파일로 출력됩니다. 결과 파일은 사용자가 플래그 또는 구성을 사용하여 지정하거나 타입스크립트 소스 파일의 구성에 따라 생성될 수 있습니다.

이 과정에서 타입스크립트 컴파일러는 tsconfig.json에 지정된 구성(있는 경우)을 따르거나 사용자가 제공한 명령줄 옵션을 통해 코드가 어떻게 트랜스파일되고 출력되어야 하는지 안내합니다. 여기에는 대상 자바스크립트 버전, 모듈 시스템, 출력 디렉토리, 엄격성 수준 등의 설정이 포함됩니다. 보다 자세한 tsconfig.json 옵션은 아래에서 살펴보겠습니다.

그리고 이렇게 생성된 자바스크립트 파일은 브라우저, node.js 또는 다른 자바스크립트 런타임 환경에서 실행할 수 있습니다.

tsconfig.json 사용하기

타입스크립트 컴파일러를 실행하기 위해서는 tsc 를 사용해야 합니다. (입력 파일 없이) tsc를 호출하면 현재 디렉터리를 시작으로 상위 디렉터리 체인으로 탐색하며 tsconfig.json 파일을 검색합니다.

입력 파일 없이 tsc와 tsconfig.json 파일이 포함된 디렉토리 경로 또는 설정이 포함된 유효한 경로의 .json 파일 경로를 지정하는 --project (또는 -p) 커맨드 라인 옵션을 사용할 수 있습니다.

tsconfig.json Examples

{
  "compilerOptions": {
    "module": "commonjs",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
		"outFile": "../../built/local/tsc.js",
    "sourceMap": true
  },
  "files": [
    "core.ts",
    "sys.ts",
    "types.ts",
    "scanner.ts",
    "parser.ts",
    "utilities.ts",
    "binder.ts",
    "checker.ts",
    "emitter.ts",
    "program.ts",
    "commandLineParser.ts",
    "tsc.ts",
    "diagnosticInformationMap.generated.ts"
  ],
	"include": ["src/**/*"],
	"exclude": ["node_modules", "**/*.spec.ts"]
}

TSConfig Bases

코드 실행 환경에 따라 쉽게 extends해서 사용할 수 있는 base 설정들이 있습니다. 해당 패키지를 설치해서 확장하여 사용할 수 있습니다.

예를 들어, node12 이상의 버전을 사용하는 프로젝트의 경우 @tsconfig/node12 패키지를 설치하여 사용할 수 있습니다.


{
  "extends": "@tsconfig/node12/tsconfig.json",
  "compilerOptions": {
    "preserveConstEnums": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}

이 외의 여러 환경에서의 추천되는 base config 파일 목록은 여기에서 확인할 수 있습니다.

CompilerOptions

compilerOptions 필드는 TypeScript 컴파일러에 .ts 파일을 컴파일하는 방법을 지시합니다.

compilerOptions에는 아래와 같은 옵션들이 정의되어 있습니다.

Type Checking

allowUnreachableCode

접근할 수 없는 코드 허용 여부를 결정합니다.

examples

아래 코드의 마지막 return 문은 어떠한 경우에도 접근할 수 없기 때문에 만약 해당 옵션이 false로 설정되어 있다면 에러를 발생시킵니다.

function fn(n: number) {
  if (n > 5) {
    return true;
  } else {
    return false;
  }
  return true;
}

undefined (default) : 경고 발생 -> 제안 사항 제공
true : 접근할 수 없는 코드 무시
false : 접근할 수 없는 코드에 대해 컴파일러 오류 발생

allowUnusedLabels

사용하지 않는 라벨 허용 여부를 결정합니다.
일반적으로 자바스크립트에서는 라벨 자체를 사용하지 않는 것이 권장되고 있습니다.

undefined (default) : 경고 발생 -> 제안 사항 제공
true : 사용하지 않는 라벨 무시
false : 사용하지 않는 라벨에 대해 컴파일러 오류 발생

alwaysStrict

파일이 ECMAScript strict mode에서 구문 분석이 되고 각 파일이 “use strict”를 내보내는지 여부를 결정합니다.

strict 값이 true이면 true 아니면 false

exactOptionalPropertyTypes

옵셔널한 객체의 값을 undefined 으로 설정할 수 있는지 여부를 결정합니다.
false인 경우 undefined로 설정 가능하지만 일반적으로 권장되지 않습니다.

true : 옵셔널 프리픽스 값이 객체 내에 존재하지 않음을 보장
false (default) : 옵셔널 프리픽스를 사용한 값에 undefined를 할당하는 것을 허용

noFallthroughCasesInSwitch

switch 문에서 fall through 케이스에 대한 오류 보고 여부를 결정합니다.

true : switch 문 내에 fall through 케이스나 존재하면 경고
false (default) : switch 문 내에 fall through 케이스나 존재해도 무시

noImplicitAny

타입 추론이 불가능하고 타입 선언도 되지 않은 값을 암묵적으로 any 타입으로 사용 하는지 여부를 결정합니다.

strict = true 인 경우 true, 그렇지 않은 경우 false

true : 암묵적으로 any 타입으로 사용하는 것을 금지
false (default) : 암묵적으로 any 타입으로 사용하는 것을 허용

noImplicitOverride

클래스를 상속받은 서브 클래스가 슈퍼 클래스의 멤버 변수나 메소드를 암묵적으로 오버라이딩하는 것을 허용할 것인지 여부를 결정합니다.

class Album {
  setup() {}
}
 
class MLAlbum extends Album {
  // 명시적 오버라이딩 허용
  override setup() {}
}
 
class SharedAlbum extends Album {
  setup() {}
Error: This member must have an 'override' modifier because it overrides a member in the base class 'Album'.
}

true : 서브 클랙스의 암묵적 오버라이딩 금지
false (default) : 서브 클래스의 암묵적 오버라이딩 허용

noImplicitReturns

함수가 암묵적으로 undefined를 반환하는 상황을 허용할 것인지를 결정합니다.

function lookupHeadphonesManufacturer(color: "blue" | "black"): string {
Function lacks ending return statement and return type does not include 'undefined'.
  if (color === "blue") {
    return "beats";
  } else {
    "bose";
  }
}

true : 함수가 암묵적으로 undefined를 반환하는 것을 금지
false (defaullt) : 함수가 암묵적으로 undefined를 반환하는 것을 허용

noImplicitThis

기본적으로 자바스크립트는 함수가 어떻게 호출되느냐에 따라 this가 동적으로 바인딩 되는데 이 방식 때문에 타입스크립트가 this의 타입 추론을 할 수 없는 상황이 발생합니다. 그 중 대표적인 예가 함수 안의 함수, 흔히들 이야기하는 Inner Function에서 this에 접근하는 경우입니다.

위와 같은 경우 this는 암묵적으로 any로 평가되는데 이런 상황을 허용할 것인지를 결정합니다.

참고 👍

class Rectangle {
  width: number;
  height: number;
 
  constructor(width: number, height: number) {
    this.width = width;
    this.height = height;
  }
 
  getAreaFunction() {
    return function () {
      return this.width * this.height;
      // 'this' implicitly has type 'any' because it does not have a type annotation.
      // 'this' implicitly has type 'any' because it does not have a type annotation.
    };
  }
}

true : this가 암묵적으로 any로 평가되는 것을 금지
false (default) : this가 암묵적으로 any로 평가되는 것을 허용

noPropertyAccessFromIndexSignature

인터페이스나 타입에 미리 정의되지 않은 프로퍼티에 . 문법을 사용하여 접근하는 것을 방어합니다.

참고👍

true : 인덱스 시그니처로 선언된 프로퍼티에 . 문법을 통해 접근하는 것을 방어
false (default) : 인덱스 시그니처로 선언된 프로퍼티에 . 문법을 통해 접근하는 것을 허용

noUncheckedIndexedAccess

인덱스 시그니처로 선언한 프로퍼티를 어떻게 추론할 것인지를 결정합니다.

true : 인덱스 시그니처로 선언된 프로퍼티를 Optional로 평가
false (default) : 인덱스 시그니처로 선언된 프로퍼티도 정의된 타입으로 평가

noUnusedLocals

사용하지 않는 지역 변수를 어떻게 처리할 것인지 결정합니다.

true : 사용하지 않는 지역 변수가 있다면 에러 발생
false (default) : 사용하지 않는 지역 변수가 있어도 무시

noUnusedParameters

사용하지 않는 인자를 어떻게 처리할 것인지 결정합니다.

true : 사용하지 않는 인자가 있다면 에러 발생
false (default) : 사용하지 않는 인자가 있어도 무시

strict

다른 strict 관련 옵션의 실행 여부를 일괄 조정합니다.

true : compilerOptions의 strict 옵션을 일괄적으로 허용
false (default) : compilerOptions의 strict 옵션을 일괄적으로 금지

strictBindCallApply

함수 호출, 바인딩 및 적용의 내장 메서드가 기본 함수에 대한 올바른 인수를 사용하여 호출되는지 확인합니다.

true : call, bind, apply 메서드 사용 시 인자의 타입 검사
false (default) : call, bind, apply 메서드 사용 시 인자의 타입 검사 허용하지 않음

strictFunctionTypes

함수의 인자를 반공변적(?)으로 평가되게 할 것인지에 대한 옵션입니다.

참고

strictNullChecks

strictNullChecks가 false면 언어에서 null 및 정의되지 않은 항목이 무시됩니다. 이로 인해 런타임에 예기치 않은 오류가 발생할 수 있습니다.

strictNullChecks가 true면 null과 undefined는 고유한 유형을 가지며, 구체적인 값이 예상되는 곳에서 이를 사용하려고 하면 타입 에러가 발생합니다.

true : 구체적인 값이 예상되는 곳에서 값이 null 또는 undefined일 가능성이 있다면 에러 발생
false (default) : 구체적인 값이 예상되는 곳에서 값이 null 또는 undefined일 가능성이 있어도 무시

strictPropertyInitialization

클래스 프로퍼티(멤버 변수)가 선언되었지만 생성자 함수에서 초기화되지 않는 경우에 에러 발생 여부를 결정합니다.

class UserAccount {
  name: string;
  accountType = "user";
 
  email: string;
Property 'email' has no initializer and is not definitely assigned in the constructor.
  address: string | undefined;
 
  constructor(name: string) {
    this.name = name;
    // Note that this.email is not set
  }
}

true : 객체 생성 시점에 멤버 변수가 초기화 되지 않았으면 에러 발생
false (default) : 객체 생성 시점에 멤버 변수가 초기화 되지 않았어도 무시

useUnknownInCatchVariables

Typescript 4.0에서 catch 절의 변수 유형을 any에서 unknown으로 변경할 수 있는 지원이 추가되었습니다.

try {
  // ...
} catch (err) {
  // We have to verify err is an
  // error before using it as one.
  if (err instanceof Error) {
    console.log(err.message);
  }
}

true : catch 문의 error 인자를 unknown으로 평가
false (default) : catch 문의 error 인자를 any로 평가

profile
FE 개발자

0개의 댓글