memostack
article thumbnail
블로그를 이전하였습니다. 2023년 11월부터 https://bluemiv.tistory.com/에서 블로그를 운영하려고 합니다. 앞으로 해당 블로그의 댓글은 읽지 못할 수 도 있으니 양해바랍니다.
반응형

Typescript 란?

Typescript는 Javascript의 상위 집합(SuperSet)인 오픈소스 프로그래밍 언어이다. Microsoft에 개발 및 유지 보수를 하고 있으며, 엄격한 문법을 지원하여, 대규모 애플리케이션을 개발하기에 용이하다.

 

기존 javascript의 문제

Javascript에서 변수는 타입을 지정하지 않고, 하나의 변수에 여러 타입의 값을 할당할 수 있어서 오류가 발생하기 쉽다. 예를들어,

let greet = 'hello world';
greet = 50;
// ...중략...
console.log(greet.split(' ')); // ERR 문자열 값을 기대했지만, 중간에 number 값이 할당되어 오류 발생

코드가 길어지고 여러 개발자가 같이 개발을 하다보면, 변수에 문자열의 값이 할당되어 있을것이라고 기대했지만, 예상하지 못한 다른 값이 할당되어 런타임 중에 오류가 발생할 수도 있다. (보통은 const 변수를 통해 재할당을 못하도록 막긴하지만, 예시를 위해 위와같이 작성해봤음)

 

Typescript 특징

 

Typescript 설치 및 설정

Typescript 설치

설치를 하는 방법은 전역으로 설치하는 방법, 특정 프로젝트에 로컬로 설치를 하는 방법 2가지 방법이 있다.

 

전역 설치

전역으로 설치하면 앞에 yarn을 붙이지 않고 사용할 수 있다는 장점이 있다.

$ yarn global add typescript

 

특정 프로젝트에 로컬로 설치

개인적으로 프로젝트마다 typescript 버전이 다를수도 있기 때문에 각 프로젝트에 로컬로 설치하는 것을 좋아한다.

$ yarn add --dev typescript

 

컴파일

위 과정을 통해 설치를 했다면, 첫 타입스크립트 파일을 작성해보자. 타입스크립트는 .ts 확장자를 가지고 있기 때문에 helloworld.ts와 같이 생성해줘야 한다.

const num: number = 10;
let myName: string = 'Hong';
var greet: string = `hello ${myName}`;

 

 

생성한 Typescript를 실행하기 위해, 컴파일 통해 Javascript 코드로 변환해줘야 한다. 이때 tsc 명령어를 사용하여 Typescript로 작성된 스크립트를 Javascript로 컴파일을 할 수 있다.

# 전역 설치를 한 경우,
$ tsc helloworld.ts

# 로컬 설치를 한 경우,
$ yarn tsc helloworld.ts

 

컴파일을 하게되면 동일한 경로 위치에 helloworld.js 파일이 생성이되어, 아래와 같이 es5 형태로 변환이된것을 확인할 수 있다.

var num = 10;
var myName = 'Hong';
var greet = "hello ".concat(myName);

 

Typescript 컴파일 옵션

--target 옵션

es5가 아닌, es6로 컴파일을 하고 싶은 경우 명령줄에 --target 옵션을 이용할 수 있다. (옵션을 넣지 않으면 default로 es5로 컴파일 됨)

 

Promise 같은 경우, es5에서 지원해주지 않기 때문에 Promise를 사용한 Typescript를 컴파일 하면 아래와 같이 오류가 발생한다.

es5로 Promise 컴파일 실패

따라서, tsc 명령줄에 --target es6 옵션을 추가한다.

$ yarn tsc filename.ts --target es6

 

컴파일 전

const num: number = 10;
let myName: string = 'Hong';
var greet: string = `hello ${myName}`;

const delay = new Promise((resolve) => setTimeout(() => resolve("1 sec"), 1000));

 

컴파일 후

es6로 컴파일 했기 때문에 const, let이 var로 변환되지 않음

const num = 10;
let myName = 'Hong';
var greet = `hello ${myName}`;
const delay = new Promise((resolve) => setTimeout(() => resolve("1 sec"), 1000));

 

--lib 옵션

lib 옵션을 이용하면, 컴파일에 필요한 라이브러리를 추가할 수 있다.

 

만약 es5로 변환하고 싶고, Promise도 사용하고 싶은 경우 --lib 옵션에 es2015.promise 라이브러리를 추가한다. (그리고 기타 필요한 라이브러리도 같이 추가)

$ yarn tsc filename.ts --lib es5,es2015.promise,dom
  • es5: global type을 사용하기 위함 (Array, Boolean, Function 등..)
  • es2015.promise: Promise를 사용하기 위함
  • dom: setTimeout, console.log 등 dom에서 지원해주는 기능들을 사용하기 위함

 

-- module 옵션

import 구문을 es6로 컴파일 했을때, 동일하게 import로 컴파일되어 node로 실행시 오류가 발생한다. 따라서, commonjs로 컴파일을 해줘야하는데, 이때 --module 옵션을 이용하여 컴파일을 한다.

$ yarn tsc helloworld.ts --target es6 --module commonjs

 

컴파일 전

import add from "./utils";
console.log(add(1, 2));

 

컴파일 후

--module commonjs 사용시 아래와 같이 commonjs 형태로 컴파일 됨

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("./utils");
console.log((0, utils_1.default)(1, 2));

 

-- showConfig 옵션

--showConfig 옵션을 사용하면, 컴파일시 사용한 옵션을 볼 수 있다.

$ yarn tsc filename.ts --target es6 --module commonjs --showConfig
{
    "compilerOptions": {
        "target": "es6",
        "module": "commonjs"
    },
    "files": [
        "./helloworld.ts"
    ]
}

 

Typescript 설정파일

매번 명령줄에 옵션을 추가해서 사용하기 번거롭기 때문에, 보통은 설정파일을 이용한다.

 

프로젝트 루트에 tsconfig.json 파일을 생성하여 옵션을 정의하면 되느데, 직접 파일을 생성해도 되지만, 많은 옵션들을 기억하기는 힘들기 때문에, 아래 명령어를 통해 tsconfig.json 설정 파일을 생성하면 편리하다.

$ yarn tsc --init

 

명령어를 수행하면 프로젝트 루트경로에 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. */
  }
}

 

추가적으로 include, exclude 등 컴파일시 필요한 기타 설정 정보를 정의할 수 있다.

{
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ],
  ...
}
  • include: 컴파일을 할 대상을 나열
  • exclude: node_modules와 같이 컴파일을 하면 안되는 대상을 나열

 

설정파일을 만들었다면, 이제는 다른 옵션 필요 없이 tsc 명령어만을 이용하여 컴파일이 가능하다.

$ yarn tsc

 

위 설정대로 타입스크립트 파일들을 src 디렉토리에 옮기고, 컴파일을 하면 아래와 같이 dist 디렉토리에 컴파일 된 javascript 파일들이 생성된다.

 

반응형
블로그를 이전하였습니다. 2023년 11월부터 https://bluemiv.tistory.com/에서 블로그를 운영하려고 합니다. 앞으로 해당 블로그의 댓글은 읽지 못할 수 도 있으니 양해바랍니다.
profile

memostack

@bluemiv_mm

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!