[Typescript] Typescript Compiler Option 다루기

ignisilva·2021년 12월 23일
1

JS/TS

목록 보기
1/1
post-thumbnail

Typescript 컴파일러 옵션들에 대해 정리보고자 한다.

tsconfig.json

Typescript로 짜여진 코드를 실행하기 위해서는 먼저 Javascript로 변환하는 트랜스파일링 과정을 거친다.

이 과정에 적용될 설정을 정리해두는 파일이 tsconfig.json이다.
(여담으로, VS code 에서는 ts파일 작성시 tsconfig.json을 기반으로 IntelliSence 기능을 제공한다.)

tsconfig.json은 직접 수동으로 생성하거나, 혹은 tsc 명령어를 사용해 생성이 가능하다.
해당 글에서는 tsc 명령어를 사용해 tsconfig.json 파일을 생성해보려 한다.

$ tsc --init

❗ tsc 명령어가 먹지 않는다면, typescript 패키지가 없는 것이므로, 설치해야 한다.

// 전역 설치
$ npm install -g typescript

명령어가 실행되고 나면, tsconfig.json 파일이 생성된다.

// tsconfig.json
{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig.json to read more about this file */

    /* Projects */
    // "incremental": true,                              /* Enable incremental compilation */
    // "composite": true,                                /* Enable constraints that allow a TypeScript project to be used with project references. */
    // "tsBuildInfoFile": "./",                          /* Specify the folder for .tsbuildinfo incremental compilation files. */
    // "disableSourceOfProjectReferenceRedirect": true,  /* Disable preferring source files instead of declaration files when referencing composite projects */
    // "disableSolutionSearching": true,                 /* Opt a project out of multi-project reference checking when editing. */
    // "disableReferencedProjectLoad": true,             /* Reduce the number of projects loaded automatically by TypeScript. */

    /* Language and Environment */
    "target": "es2016",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
    // "lib": [],                                        /* Specify a set of bundled library declaration files that describe the target runtime environment. */
    // "jsx": "preserve",                                /* Specify what JSX code is generated. */
    // "experimentalDecorators": true,                   /* Enable experimental support for TC39 stage 2 draft decorators. */
    // "emitDecoratorMetadata": true,                    /* Emit design-type metadata for decorated declarations in source files. */
    // "jsxFactory": "",                                 /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
    // "jsxFragmentFactory": "",                         /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
    // "jsxImportSource": "",                            /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
    // "reactNamespace": "",                             /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
    // "noLib": true,                                    /* Disable including any library files, including the default lib.d.ts. */
    // "useDefineForClassFields": true,                  /* Emit ECMAScript-standard-compliant class fields. */

    /* Modules */
    "module": "commonjs",                                /* Specify what module code is generated. */
    // "rootDir": "./",                                  /* Specify the root folder within your source files. */
    // "moduleResolution": "node",                       /* Specify how TypeScript looks up a file from a given module specifier. */
    // "baseUrl": "./",                                  /* Specify the base directory to resolve non-relative module names. */
    // "paths": {},                                      /* Specify a set of entries that re-map imports to additional lookup locations. */
    // "rootDirs": [],                                   /* Allow multiple folders to be treated as one when resolving modules. */
    // "typeRoots": [],                                  /* Specify multiple folders that act like `./node_modules/@types`. */
    // "types": [],                                      /* Specify type package names to be included without being referenced in a source file. */
    // "allowUmdGlobalAccess": true,                     /* Allow accessing UMD globals from modules. */
    // "resolveJsonModule": true,                        /* Enable importing .json files */
    // "noResolve": true,                                /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */

    /* JavaScript Support */
    // "allowJs": true,                                  /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
    // "checkJs": true,                                  /* Enable error reporting in type-checked JavaScript files. */
    // "maxNodeModuleJsDepth": 1,                        /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */

    /* Emit */
    // "declaration": true,                              /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
    // "declarationMap": true,                           /* Create sourcemaps for d.ts files. */
    // "emitDeclarationOnly": true,                      /* Only output d.ts files and not JavaScript files. */
    // "sourceMap": true,                                /* Create source map files for emitted JavaScript files. */
    // "outFile": "./",                                  /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
    // "outDir": "./",                                   /* Specify an output folder for all emitted files. */
    // "removeComments": true,                           /* Disable emitting comments. */
    // "noEmit": true,                                   /* Disable emitting files from a compilation. */
    // "importHelpers": true,                            /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
    // "importsNotUsedAsValues": "remove",               /* Specify emit/checking behavior for imports that are only used for types */
    // "downlevelIteration": true,                       /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
    // "sourceRoot": "",                                 /* Specify the root path for debuggers to find the reference source code. */
    // "mapRoot": "",                                    /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true,                          /* Include sourcemap files inside the emitted JavaScript. */
    // "inlineSources": true,                            /* Include source code in the sourcemaps inside the emitted JavaScript. */
    // "emitBOM": true,                                  /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
    // "newLine": "crlf",                                /* Set the newline character for emitting files. */
    // "stripInternal": true,                            /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
    // "noEmitHelpers": true,                            /* Disable generating custom helper functions like `__extends` in compiled output. */
    // "noEmitOnError": true,                            /* Disable emitting files if any type checking errors are reported. */
    // "preserveConstEnums": true,                       /* Disable erasing `const enum` declarations in generated code. */
    // "declarationDir": "./",                           /* Specify the output directory for generated declaration files. */
    // "preserveValueImports": true,                     /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */

    /* Interop Constraints */
    // "isolatedModules": true,                          /* Ensure that each file can be safely transpiled without relying on other imports. */
    // "allowSyntheticDefaultImports": true,             /* Allow 'import x from y' when a module doesn't have a default export. */
    "esModuleInterop": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
    // "preserveSymlinks": true,                         /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
    "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */

    /* Type Checking */
    "strict": true,                                      /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                            /* Enable error reporting for expressions and declarations with an implied `any` type.. */
    // "strictNullChecks": true,                         /* When type checking, take into account `null` and `undefined`. */
    // "strictFunctionTypes": true,                      /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
    // "strictBindCallApply": true,                      /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
    // "strictPropertyInitialization": true,             /* Check for class properties that are declared but not set in the constructor. */
    // "noImplicitThis": true,                           /* Enable error reporting when `this` is given the type `any`. */
    // "useUnknownInCatchVariables": true,               /* Type catch clause variables as 'unknown' instead of 'any'. */
    // "alwaysStrict": true,                             /* Ensure 'use strict' is always emitted. */
    // "noUnusedLocals": true,                           /* Enable error reporting when a local variables aren't read. */
    // "noUnusedParameters": true,                       /* Raise an error when a function parameter isn't read */
    // "exactOptionalPropertyTypes": true,               /* Interpret optional property types as written, rather than adding 'undefined'. */
    // "noImplicitReturns": true,                        /* Enable error reporting for codepaths that do not explicitly return in a function. */
    // "noFallthroughCasesInSwitch": true,               /* Enable error reporting for fallthrough cases in switch statements. */
    // "noUncheckedIndexedAccess": true,                 /* Include 'undefined' in index signature results */
    // "noImplicitOverride": true,                       /* Ensure overriding members in derived classes are marked with an override modifier. */
    // "noPropertyAccessFromIndexSignature": true,       /* Enforces using indexed accessors for keys declared using an indexed type */
    // "allowUnusedLabels": true,                        /* Disable error reporting for unused labels. */
    // "allowUnreachableCode": true,                     /* Disable error reporting for unreachable code. */

    /* Completeness */
    // "skipDefaultLibCheck": true,                      /* Skip type checking .d.ts files that are included with TypeScript. */
    "skipLibCheck": true                                 /* Skip type checking all .d.ts files. */
  }
}

Options

생성된 tsconfig.json에 보면, 굉장히 많은 옵션들이 있음을 알 수 있다.

그래서 자주 쓰는 Option들에 대해 정리를 해보려한다.

자주 쓰는 Option 선정은 Zerocho 님의 강의를 기준으로 했다.

//tsconfig.json
{
  "compilerOptions": {
  
    // js 파일의 사용 허용 옵션, 프로젝트가 js에서 ts로 마이그레이션 중일 때 사용한다.
    // allowJS: true,
    
    // 모듈을 import, 또는 require할 시, 절대 경로를 사용을 위한 rootDir 설정 옵션
    // ex) 
    // baseUrl
    // ├── ex.ts
    // ├── hello
    // │   └── world.ts
    // └── tsconfig.json
    // 
    // in ex.ts
    // import { helloWorld } from "hello/world";
    //
    "baseUrl": "./",
    
    // d.ts 파일 생성 관련 옵션
    // d.ts 파일은 변수 및 커스텀 생성한 Type 등에 대한 명세를 보여준다. 
    "declaration": true,
    
    // 모듈 호출시, ES호환성 관련 옵션
    // TS에서, 아래의 두 줄의 ES6 코드는 모듈시스템 내부 동작에 의해 모듈이 호출 방식이 같지 않다.
    // import moment from 'moment';      (=== const moment = require("moment"))
    // import * as moment from 'moment'; (=== const moment = require("moment").default)
    // 
    // 공식적인 호출 방식은 두번째 방법이며, 
    // 따라서 첫번째 방식으로 호출 할 경우 에러가 발생한다.
    //
    // esModuleInterop 옵션 활성화 시, importHelpers 옵션이 활성화되며,
    // 첫번째 방식으로도 모듈을 호출 할 수 있게 된다.
    "esModuleInterop": true,
    
    // ts 데코레이터 관련 옵션, relect-metadata 모듈을 기반으로 하는 메타데이터의 사용 설정 옵션이다.
    // 데코레이터 사용시, true
    "emitDecoratorMetadata": true,
    
    // ts 데코레이터 관련 옵션, 데코레이터 실험적 사용 설정 옵션이다.
    // 실험적 사용이라는 표현이 사용되는 이유는 데코레이터는 아직 JS 공식 승인 언어 기능이 아니기 때문이다.
    // 데코레이터 사용시, true
    "experimentalDecorators": true,
    
    // JS파일 안의 Jsx 구성을 어떻게 할지 제어하는 설정
    // .tsx로 시작한 JS파일의 결과에만 영향이 있다.
    // 올 수 있는 값과 예시는 아래와 같다.
    //
    // // sample code
    // export const helloWorld = () => <h1>Hello world</h1>
    //
    // "react" (default)
    // import React from 'react';
    // export const helloWorld = () => React.createElement("h1", null, "Hello world");
    //
    // "preserve"
    // import React from 'react';
    // export const helloWorld = () => <h1>Hello world</h1>;
   	// 
    // "react-native"
    // import React from 'react';
    // export const helloWorld = () => <h1>Hello world</h1>;
    //
    // "react-jsx"
    // import { jsx as _jsx } from "react/jsx-runtime";
    // import React from 'react';
    // export const helloWorld = () => _jsx("h1", { children: "Hello world" }, void 0);
    //
    // "react-jsxdev"
    // import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
    //	const _jsxFileName = "/home/runner/work/TypeScript-Website/TypeScript-Website/index.tsx";
	// import React from 'react';
	// export const helloWorld = () => _jsxDEV(
    // 		"h1", { children: "Hello world" }, void 0, false, { 
    //			fileName: _jsxFileName, lineNumber: 9, 	columnNumber: 32 
    //      }, 
    //      this);
    "jsx": "preserve"
    
    // ts에는 내장 js API (Math 등)에 대한 기본 유형 정의 및 브라우저 환경의 유형 정의 등이 포함되어 있다.
    // 이러한 유형 정의 set을 어떤 버전으로 이용할 것인지에 대한 설정 옵션
    // 
    // Option 종류
    // ES5 / ES2015(ES6) / ES2016(ES7) / ES2017 / ES2018
    // ES2019 / ES2020 / ES2021 / ESNext / DOM / WebWorker / ScriptHost
    // 각 버전 별로 추가되는 유형 정의가 있다 (자세한 내용은 하단에 이미지 참고)
    //
    // ts로 최신 문법 작성시 에러가 발생한다면, 해당 문법의 유형 정의를 가지고 있는 버전을 lib 옵션에 추가해야한다.
    // (ES6를 추가할 시, ES2020과 ES2019를 같이 넣어주는 것이 좋다)
    "lib": ["DOM", "ES5", "ES2015"],
    
    // 빌드된 결과물이 어떤 런타임 환경에서 실행 가능한지에 대한 설정
    // default는 es3 이지만, 권장은 ES6이다.
    // 해당 값을 변경하면, lib 값도 같이 변경된다.
    "target": "ES6",
    
    // 빌드될 프로젝트의 루트 디렉토리를 지정
    // 해당 디렉토리를 기준으로 빌드가 이뤄짐
    "rootDir": "./src",
    
    // 빌드된 결과물이 저장될 디렉토리를 지정
    "outDir": "./dist",
    
    // type definition파일(*.d.ts)을 어디에서 불러올지 설정하는 옵션
    // defalut 경로: node_modules/@types/PACKAGE_NAME/index.d.ts
    // 
    // typeRoots와 types 옵션은 같이 사용하지 않는다.
    //
    // typeRoots는 배열 안의 경로에서만 type definition 파일을 불러온다.
    // tpyeRoots 배열은 인자로 경로 값을 가진다.
    // 
    // types는 배열 안의 경로 또는 default 경로에서 PACKAGE_NAME을 찾아 파일을 불러온다.
    // types 배열은 인자로 패키지 이름 값을 가진다.
    "typeRoots": ["PATH"],
    "types": ["PACKAGE_NAME"],
    
    
    // Type을 엄격하게 검사할 것인지 설정하는 옵션 (true 권장)
    // strict: true라면, strict에 종속되는 옵션들은 전부 true 값을 가진다.
    "strict": true,
    
    // 현 프로그램을 위한 모듈 로더(loader)을 설정하는 옵션
    // 모듈 로더?
    // 모듈을 불러와서 실행시키는 프로그램
    // Options
    // CommonJS / UMD / AMD / System / ESNext / ES2020 / ES6
   	"module": "MODULE_NAME",
}

Option들에 대한 더 자세한 내용은 tsconfig.json 파일 내에 있는 Docs링크를 통해 알아볼 수 있다.

참고 이미지

<lib option 관련 참고 자료>

<module option 관련 참고 자료>

profile
웹 개발자

0개의 댓글