본문 바로가기

TypeScript

[TypeScript] TypeScript 초보자를 위한 tsconfig.json 가이드

 

 

타입스크립트를 초기화 하려면 글로벌 인스톨을 먼저 합니다.

타입스크립트는 개발 단계에서만 사용하고 컴파일 시에는 자바스크립트로 변환되므로

devDependencies 에 인스톨 해주면 됩니다.

 

npm i -D typescript

 

ts 파일을 js 파일로 컴파일 하기 위해선 터미널에 'tsc 파일명' 을 입력하면 js 파일로 변환이 됩니다.

하지만 매번 코드를 수정, 작성하고 터미널에서는 tsc 명령어를 입력하기에는 너무 번거롭습니다.

 

그래서 tsconfig.json 을 생성하여 저장될 때마다 자동 컴파일이 되도록 설정을 하는 것입니다.

 

그 후 타입스크립트의 기본 설정을 위한 tsconfig.json 생성을 위해

아래 명령어를 프로젝트 루트 터미널에 입력합니다.

tsc --init

 

그럼 기본 설정에 관한 속성 및 설명이 주석으로 표시 됩니다.

 

exclude는 기본적으로 compilerOptions 밖에 컴파일 시 제외할 대상으로 

node_modules 를 포함시켜 줍니다. 반대 개념인 include 나 files 도 있으나 많이 안쓰는 속성으로  생략하겠습니다.

( 다만 includes는 ["src/**/*"] 처럼 경로 및 단위 파일로 설정이 가능하고

files 옵션은 단위 파일들만 설정이 가능하다는 차이가 있습니다)

 

 

1. 기본 속성들 

 

* 표시는 필수, 나머지는 상황이나 취향에 따라

compilerOptions 속성명 설명 예시
target * 컴파일할 es 버전을 선택할 수 있습니다 "target": "es6"
"target": "es5" 로 하면 let, const 가 
var 로 변경되는 식( es5는 var 만 있음)
lib * 컴파일에 포함될 라이브러리 파일 목록입니다.
생략했다면 target이 es5 냐 es6냐에 따라 기본 주입되는 라이브러리가 달라집니다.
- ES5: DOM,ES5,ScriptHost
- ES6: DOM,ES6,DOM.Iterable,ScriptHost
allowJs 컴파일에 js 파일도 포함시킨다
( checkJs 와 세트로 전 사용합니다 )
- JavaScript 프로젝트를 점진적으로
  TS로 마이그레이션할 때

- 일부 JavaScript 라이브러리를
   TS 프로젝트에서 사용해야 할 때

- 기존 JavaScript 파일과 새로운
   TS 파일을 함께 사용할 때
checkJs js 파일을 컴파일 하진 않고, 구문검사 및 잠재적 오류만 보고한다 - JSDoc 주석을 통한 타입 힌트를 인식합니다
sourceMap * true 로 설정시 
원본 TS 코드를 보면서 브라우저 개발자 도구에서 디버깅 가능
 
outDir * 컴파일된 JS파일을 보관할 경로
설정한 폴더를 먼저 만들어야 한다
    "outDir": "./dist",  
rootDir * 컴파일할 TS 파일의 경로, 다중선택 가능
설정한 폴더를 먼저 만들어야 한다
"rootDirs": ["./src", "./src/components"]
removeComments JS로 컴파일시 TS 파일에 달린 주석 제거  
noEmit 오류 검사는 하되 컴파일시 JS 파일을 안 만듦  
downlevelIteration for 루프 등의 반복문의 경우 간혹 에러가 나는 경우가 있다. 그때 사용 아래 블로그 링크를 참조
TypeScript iterated 에러 수정
noEmitOnError 타입 오류가 있을 때 JS 파일을 생성하지 않도록 하는 옵션  
forceConsistentCasingInFileNames 파일 이름 대소문자 일관성 체크  
module 모듈 시스템 설정( Node.js 프로젝트  ) commonjs, es6, esnext 등
esModuleInterop CommonJS 모듈을 ES6 모듈처럼 사용 가능
( Node.js 프로젝트  )
 
jsx React 사용시 JSX 처리 방식 설정
( React 프로젝트 )
 
skipLibCheck 선언 파일(*.d.ts)의 타입 체크 스킵  
resolveJsonModule JSON 모듈 import 허용  

 

 

 

2. 타입체크 속성들 ( strict :true시 활성화 되는 옵션들)

compilerOptions 속성명 설명
strict 아래 옵션을 개별적으로 설정하는 것과 동일
noImplicitAny 암시적 'any' 타입을 허용하지 않습니다.
strictNullChecks  'null'과 'undefined'을  허용하지 않습니다
strictFunctionTypes 함수 타입에 대한 더 엄격한 검사를 수행합니다.
strictBindCallApply bind, call, apply 메서드 사용 시 더 엄격한 타입 체크를 합니다
strictPropertyInitialization 클래스 속성 초기화 검사를 수행합니다
strictBuiltinIteratorReturn 내장 이터레이터의 반환 타입을 더 엄격하게 검사합니다.()
noImplicitThis 'this' 타입이 암시적 'any'인 경우 에러를 발생시킵니다.
useUnknownInCatchVariables catch 블록의 에러 변수를 'unknown' 타입으로 처리합니다
alwaysStrict 모든 소스 파일에 "use strict"를 추가하고 strict 모드로 파싱합니다.

 

 

 

3. 코드 품질 속성들 

compilerOptions 속성명  설명
noUnusedLocals 사용되지 않는 지역 변수를 체크합니다.
noUnusedParameters 사용되지 않는 매개변수를 체크합니다.
exactOptionalPropertyTypes 선택적 프로퍼티의 타입을 더 엄격하게 처리합니다.
noImplicitReturns 함수 내 모든 코드 경로가 값을 반환하는지 체크합니다.
noFallthroughCasesInSwitch switch문에서 fallthrough 케이스를 방지합니다.
noUncheckedIndexedAccess 인덱스 접근 시 undefined를 포함하도록 합니다.
noImplicitOverride 부모 클래스의 메서드를 오버라이드할 때 'override' 키워드를 강제합니다.
noPropertyAccessFromIndexSignature 인덱스 시그니처로 선언된 프로퍼티의 점 표기법 접근을 제한합니다.
allowUnusedLabels 사용되지 않는 레이블을 허용할지 설정합니다.
allowUnreachableCode 도달할 수 없는 코드를 허용할지 설정합니다.
// noImplicitAny: true
// 암시적 'any' 타입을 허용하지 않습니다.

function fn(s) {  // 매개변수 s의 타입이 암시적 any, 에러 발생
    console.log(s.subtr(3));
}

// 올바른 사용
function fn(s: string) {
    console.log(s.substr(3));
}


// **************************


// strictNullChecks: false
let name: string = null;  // 허용

// strictNullChecks: true
let name: string = null;  // 에러
let nullableName: string | null = null;  // 정상


// **************************


// strictFunctionTypes: true
// 함수 타입에 대한 더 엄격한 검사를 수행합니다

interface Animal { name: string }
interface Dog extends Animal { bark(): void }

let f1: (a: Animal) => void = (d: Dog) => {};  // 에러
let f2: (d: Dog) => void = (a: Animal) => {};  // 정상


// **************************

// strictBindCallApply: true
// bind, call, apply 메서드 사용 시 더 엄격한 타입 체크를 합니다.

function fn(x: string) {
    return parseInt(x);
}

fn.call(null, 10);  // 에러: 숫자를 문자열 파라미터에 전달할 수 없음


// **************************


// strictPropertyInitialization: ture
// 클래스 속성 초기화 검사를 수행합니다.

class User {
    name: string;  // 에러: 초기화되지 않음
    age: number = 0;  // 정상
}


// **************************


// strictBuiltinIteratorReturn: ture
// 내장 이터레이터의 반환 타입을 더 엄격하게 검사합니다.

function* generator(): Generator<number, void, unknown> {
    yield 1;
    return "done";  // 에러: void 타입이 예상되는데 string이 반환됨
}


// **************************
// noImplicitThis: ture
// 'this' 타입이 암시적 'any'인 경우 에러를 발생시킵니다.

function fn() {
    console.log(this.x);  // 에러: 'this'의 타입이 암시적 any
}


// **************************


// useUnknownInCatchVariables: ture
// catch 블록의 에러 변수를 'unknown' 타입으로 처리합니다.

try {
    // ...
} catch (error) {  // error는 unknown 타입
    // error.message  // 에러: unknown 타입에서 직접 접근 불가
    if (error instanceof Error) {
        console.log(error.message);  // 정상: 타입 체크 후 접근
    }
}


// **************************


// alwaysStrict: ture
// 모든 소스 파일에 "use strict"를 추가하고 strict 모드로 파싱합니다.

// 컴파일된 결과
"use strict";
function fn() {
    // ...
}


// **************************

// noUnusedLocals & noUnusedParameters
// 사용되지 않는 지역 변수와 매개변수를 체크합니다.

function fn(unused: string) {  // 경고: 매개변수가 사용되지 않음
    const x = 10;  // 경고: 변수가 사용되지 않음
    return 20;
}


// **************************

// exactOptionalPropertyTypes
// 선택적 프로퍼티의 타입을 더 엄격하게 처리합니다.

interface User {
    name?: string;
}

const user: User = {
    name: undefined  // 에러: undefined를 직접 할당할 수 없음
};

const validUser: User = {};  // 정상: 프로퍼티 자체를 생략


// **************************


// noImplicitReturns: ture
// 함수 내 모든 코드 경로가 값을 반환하는지 체크합니다.

function fn(x: number) {  // 에러: 모든 경로가 값을 반환하지 않음
    if (x > 0) {
        return x;
    }
    // else 경로에서 반환값 없음
}


// **************************


// noFallthroughCasesInSwitch: true
// switch문에서 fallthrough 케이스를 방지합니다.

switch (x) {
    case 0:  // 에러: break 또는 return 필요
        console.log("zero");
    case 1:
        console.log("one");
        break;
}


// **************************


// noUncheckedIndexedAccess: true
// 인덱스 접근 시 undefined를 포함하도록 합니다.

const arr = [1, 2, 3];
const value = arr[0];  // value의 타입: number | undefined

const obj = { a: 1, b: 2 };
const val = obj['a'];  // val의 타입: number | undefined


// **************************


// noImplicitOverride: true
// 부모 클래스의 메서드를 오버라이드할 때 'override' 키워드를 강제합니다

class Base {
    walk() {}
}

class Derived extends Base {
    override walk() {}  // override 키워드 필요
}


// **************************


// noPropertyAccessFromIndexSignature: true
// 인덱스 시그니처로 선언된 프로퍼티의 점 표기법 접근을 제한합니다.

interface Dictionary {
    [key: string]: string;
}

const dict: Dictionary = { key: "value" };

// noPropertyAccessFromIndexSignature: true
dict.key;      // 에러: 점 표기법 사용 불가
dict["key"];   // 정상: 대괄호 표기법 사용


// **************************


// allowUnusedLabels: true
// 사용되지 않는 레이블을 허용할지 설정합니다.


// allowUnusedLabels: false (기본값)
loop: while(true) {  // 경고: 레이블이 사용되지 않음
    break;
}

// allowUnusedLabels: true
loop: while(true) {  // 경고 없음
    break;
}


// **************************


// allowUnreachableCode : true
// 도달할 수 없는 코드를 허용할지 설정합니다.

// allowUnreachableCode: false (기본값)
function fn() {
    return true;
    console.log("Hi");  // 경고: 도달할 수 없는 코드
}

// allowUnreachableCode: true
function fn() {
    return true;
    console.log("Hi");  // 경고 없음
}

 

 

 

 

 

https://www.typescriptlang.org/ko/docs/handbook/tsconfig-json.html

 

Documentation - What is a tsconfig.json

Learn about how a TSConfig works

www.typescriptlang.org

https://www.typescriptlang.org/ko/docs/handbook/compiler-options.html

 

Documentation - tsc CLI Options

A very high-level overview of the CLI compiler options for tsc

www.typescriptlang.org

 

https://velog.io/@boyeon_jeong/TypeScript-iterated-%EC%97%90%EB%9F%AC-%EC%88%98%EC%A0%95downlevelIteration-target

 

TypeScript iterated 에러 수정(downlevelIteration, target)

TS2802: Type 'Set ' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher. TypeScript에서 S

velog.io