[TypeScript] CLASSES AND INTERFACES #5.0 - 5.4

uxolrv·2022년 12월 22일
0

nomadCoder - TypeScript

목록 보기
9/9
post-thumbnail

📌 TypeScript 프로젝트 초기 설정


보통 Create-React-App(CRA), Next.js, Nest.js를 통해 프로젝트를 생성할 경우, 타입스크립트 프로젝트 설정 파일을 따로 수동으로 작성해 줄 필요 없다.

⇒ 이러한 프레임워크, 라이브러리는 타입스크립트 프로젝트를 자동 생성해주기 때문!




1️⃣ 패키지 생성

npm init -y


y 옵션을 붙이지 않고 npm init을 실행할 경우, 위 양식에 대해 일일이 값을 입력해야 하지만, y 옵션을 사용할 경우, default값으로 설정된 package.json 파일을 생성해준다. (y는 "yes"라는 의미)




2️⃣ 타입스크립트 설치

npm install -D typescript

D 옵션을 사용하여, devDependencies에 타입스크립트를 설치해준다.




3️⃣ index.ts 파일 생성

const hello = () => console.log("hi");

컴파일이 잘 되는 지 확인해보기 위해 임의로 함수를 작성해본다.




4️⃣ tsconfig.json 파일 생성

tsconfig.json 파일은 이 디렉토리가 TypeScript 프로젝트임을 나타낸다.
tsconfig.json은 TypeScript 프로젝트를 컴파일하는 데 필요한 루트 파일과 컴파일러 옵션을 지정한다.


✅ 타입스크립트 파일 경로 설정

"include": ["src"]

include의 배열 안에 자바스크립트로 컴파일하고 싶은 모든 디렉토리를 넣어주면 된다.



✅ 자바스크립트 파일이 생성될 디렉토리 지정

// tsconfig.json

"compilerOptions": {
  "outDir": "build"
}

build 폴더에 JS파일이 생성되도록 설정하였다.


// package.json

"scripts": {
  "build": "tsc"
},



// terminal

npm run build

package.json을 위와 같이 작성한 후, 터미널에서 npm run build를 실행하면 tsc가 작동한다.


src 디렉토리 속 ts 파일들이 js 파일로 컴파일되어 build 디렉토리에 저장되는 것을 확인할 수 있다


// index.ts

const hello = () => console.log("hi");
// index.js

var hello = function () { return console.log("hi"); };

index.js을 확인해보면, index.ts에서 작성한 함수 형태와 다른 것을 확인할 수 있다.

이는 타입스크립트가 낮은 버전의 자바스크립트 코드로 컴파일한 것이다.
⇒ 어디에서든 이해할 수 있는 호환성 좋은 자바스크립트 코드로 컴파일된 것

✨ 그러나, 어떤 버전의 자바스크립트로 컴파일할 지는 변경이 가능하다!



✅ 컴파일 후의 자바스크립트 버전 설정

  "compilerOptions": {
    "target": "ES6"
  }

target은 타입스크립트 컴파일 후의 자바스크립트 버전을 결정한다. (기본값 ES3)
만약 코드가 이전 환경에 배포된 경우 더 낮은 target을 설정하거나 최신 환경에서 코드 실행이 보장되는 경우 더 높은 target을 설정하도록 선택할 수 있다.

화살표 함수는 ES3에서는 지원하지 않기 때문에 함수 표현식으로 컴파일이 된다.


// index.ts

class Block {
  constructor(private data: string) {}
  static hello() {
    return "hi";
  }
}

만약 target 값이 ES3인 상태에서 class 문법을 컴파일하면?


// index.js

var Block = /** @class */ (function () {
    function Block(data) {
        this.data = data;
    }
    Block.hello = function () {
        return "hi";
    };
    return Block;
}());

타입스크립트가 클래스가 존재하지 않는 버전의 자바스크립트에서 클래스를 시뮬레이션해준다.


ES3와 같이 낮은 버전으로 설정할 경우 코드가 너무 길어질 수 있으며, ES2022와 같이 지나치게 최신버전으로 설정할 경우 호환성 문제가 발생할 수 있다.

⇒ ✨ 대부분의 nodeJS와 브라우저에서 ES6를 지원하므로, target은 ES6로 설정하는 것이 가장 이상적이다.



✅ 타겟 런타임 환경 설정

TypeScript에는 내장 JS API(예: Math)에 대한 기본 유형 정의 세트와 브라우저 환경에서 발견되는 항목에 대한 유형 정의(예: document)가 포함되어 있다.

⇒ 이로 인해 lib 옵션으로 어떤 환경에서 코드를 실행할 지 지정할 수 있다.

만일 targetES5으로 설정한 상태에서 ES6에서 지원하는 Promise를 사용하고 싶다면, lib 배열에 ES6를 추가해야 한다.


"compilerOptions": {
  "lib": ["ES6", "DOM"]
}

lib 옵션에 DOM을 추가하고 나면, document, window, localStorage 등의 객체를 사용할 수 있다.



document.querySelector를 입력한 후 command를 눌러 클릭하면, lib.dom.d.ts 파일로 이동하게 된다.

해당 파일은 node_modules > typescript > lib 에 위치해 있으며, document 객체에 포함된 메서드들의 타입이 정의되어 있음을 확인할 수 있다.


⇒ ✨ lib.dom.d.ts은 dom 환경에서 사용할 수 있는 메서드 및 이벤트의 타입을 정의해둔 정의 파일 (Declaration File)!

⇒ ✨ 정의 파일이 있기 때문에 document 객체에 포함된 메서드의 타입을 따로 정의하지 않아도 메서드를 사용할 수 있는 것!



위처럼 localStorage.setItem() 작성 시, 인자의 타입과 return 타입 및 메서드에 대한 간단한 설명을 확인할 수 있다!




✅ strict 모드 설정

모든 엄격한 타입 검사 옵션을 활성화한다.

"compilerOptions": {
  "strict": true
}

strict 모드를 활성화할 경우, 프로그램 정확성을 더 강력하게 보장하는 광범위한 타입 검사가 동작한다.










📌 TypeScript 프로젝트 추가 설정

🔎 case 1: node_modules에 설치된 자바스크립트 모듈을 타입스크립트 프로젝트에서 사용하려면?

// myPackage.js

export function init(config) {
  return true;
}

export function exit(code) {
  return code + 1
}

myPackage.js가 node_modules의 자바스크립트의 모듈이라고 가정해보자.
myPackage.js 파일에 적힌 자바스크립트 코드의 타입을 타입스크립트는 알 수가 없다.

이 상태에서 index.ts 파일에서 myPackage를 node의 모듈인 것처럼 사용한다면?



// index.ts

import { init } from "myPackage";
// Err: Could not find a declaration file for moodule 'myPackage'.

정의 파일을 찾을 수 없다는 에러가 발생한다.

⇒ ✨ myPackage.d.ts 파일(정의 파일)을 만들어 타입을 정의해주어야 한다!




💡 Declaration File(정의 파일) 이란?

JavaScript 코드를 TypeScript에게 설명해주는 파일

TypeScript에는 내장 JS API(예: Math)에 대한 기본 유형 정의 세트와 브라우저 환경에서 발견되는 항목에 대한 유형 정의(예: document)가 포함되어 있다.

⇒ 정의 파일이 내장되어 있으므로, lib 옵션에서 환경 설정을 해 줄 경우, 따로 정의 파일을 만들지 않아도 된다!


우리가 사용하는 프레임워크, 라이브러리 등의 패키지는 타입스크립트가 아닌 자바스크립트로 만들어져있다.

그러므로 자바스크립트로 만들어진 라이브러리를 타입스크립트 프로젝트에서 사용하려면, 타입 정의가 필요하다.

// myPackage.d.ts
interface Config {
  url: string;
}

declare module "myPackage" {
  function init(config: Config): boolean;
  function exit(code: number): number;
}

d.ts 파일에서 모듈에 대한 call signature를 작성해 준다.



정의 파일을 작성하고 나면, 타입스크립트가 함수 init의 타입을 알고 있기 때문에 더 이상 에러가 발생하지 않게 된다.


함수 initexit에 대한 타입이 d.ts파일에 정의되어 있으므로, 함수 initexit를 사용할 때 따로 타입을 작성하지 않아도 된다.








🔎 case 2: .js 파일을 .ts 파일에서 불러와 사용하려면?

한 프로젝트 안에 자바스크립트 파일과 타입스크립트 파일이 공존하는 경우를 종종 볼 수 있다. (ex. JS 프로젝트를 TS 프로젝트로 이전하는 경우)



만약 ts 파일에서 js 파일을 import하려 한다면?

// index.ts

import { init, exit } from "./myPackage";
// Err: './myPackage' 모듈을 찾을 수 없습니다.

에러가 발생한다.



// tsconfig.json

"compilerOptions": {
  "allowJs": true
}

allowJs 옵션을 true로 설정할 경우, TypeScript 프로젝트 내에서 JavaScript 파일을 import할 수 있게 된다.



다시 index.ts를 보면 import문에서 더 이상 에러가 발생하지 않음을 확인할 수 있으며, myPackage.js의 함수 init 코드를 분석하여 init의 타입을 추론해주는 모습까지 확인할 수 있다.








🔎 case 3: .js 파일에서 타입스크립트의 보호 장치를 사용하려면?

// @ts-check를 추가하여 TypeScript가 JavaScript 코드를 분석하도록 할 수 있다.

이러한 오류를 무시하고 싶다면 // @ts-ignore 또는 // @ts-expect-error를 추가하여 특정 줄의 오류를 무시할 수 있다.



myPackage.js
// @ts-check

export function init(config) {
  return true;
}

export function exit(code) {
  return code + 1;
}

// @ts-check를 .js파일의 첫 번째 줄에 추가하면 TypeScript가 오류를 발생시킨다.



myPackage.js
// @ts-check

// Err: 형식 주석은 TypeScript 파일에서만 사용할 수 있습니다.
export function init(config: object) {     
  return true;
}

export function exit(code) {
  return code + 1;
}

이는 js 파일이기 때문에 타입을 작성할 수 없다!

자바스크립트 코드를 건들지 않은 채, 타입스크립트가 제공하는 보호 장치를 사용하고 싶다면?

⇒ ✨ JSDoc 이용!




💡 JSDoc

JavaScript 파일에 주석을 사용하여 type 정보를 제공할 수 있는 문법

함수 위에 주석으로 작성하면 된다.

myPackage.js
// @ts-check

/**
 * Initializes the project
 * @param {object} config 
 * @param {boolean} config.debug
 * @param {string} config.url
 * @returns {boolean}
 */
export function init(config) {
  return true;
}

/**
 * Exits the program
 * @param {number} code 
 * @returns {number}
 */
export function exit(code) {
  return code + 1;
}

params 타입과 return 타입을 작성하면 타입스크립트가 해당 주석을 감지하여 타입을 체크해준다.

물론, ts 파일이 아닌 js 파일이므로 브라우저에서는 문제없이 실행된다.



myPackage.js에서 JSDoc을 작성한 후, index.ts에서 init을 사용해보면 작성했던 JSDoc 내용을 확인할 수 있다.










profile
안녕하세연🙋 프론트엔드 개발자입니다

0개의 댓글