본문 바로가기
Notes/TypeScript

TypeScript Chapter. 5

by seyoonagain 2024. 12. 9.

TypeScript


에러 처리

에러 객체의 타입을 any로 지정하는 경우,
error.message로 접근했을 때, 전달받은 message가 없는 경우 런타임 에러가 발생할 수 있으므로,
any가 아닌 unknown으로 지정하고,
해당 에러가 Error 객체의 인스턴스가 맞는지 확인한 후 에러 처리가 가능하도록 코드를 작성한다.

try {
  // 에러가 발생할 수 있는 코드
  // throw new Error('something went wrong')
} catch (error: unknown) {
  if (error instanceof Error) {
    console.log(error.message); // 'something went wrong'
  }
} finally {
  // 에러 발생 여부에 관계없이 항상 실행되는 코드
}

다양한 상황에서 발생할 수 있는 에러를 클래스로 커스텀하여 사용할 수 있다.

class CustomError extends Error {
  constructor(message: string) {
    super(message);
    this.name = 'CustomError';
  }
}

try {
  throw new CustomError('custom error message...');
} catch (error) {
  if (error instanceof CustomError) {
    console.error(error.message);
  }
}

비동기 프로그래밍

Promise 객체

비동기 작업 후 반환되는 객체로,
작업의 성공 여부에 따라 각각 resolve()/reject() 콜백 메서드를 실행한다.

const sync = () => {
  console.log('동기 작업 완료');
};

const asyncFn = () => {
  return new Promise((resolve) => {
    resolve('비동기 작업 완료');
  });
};

function main() {
  sync();
  asyncFn().then(console.log);
  sync();
  sync();
}

main();
/**
 * 출력 순서
동기 작업 완료
동기 작업 완료
동기 작업 완료
비동기 작업 완료
 */

제네릭 Promise

Promise<T>: 비동기 작업 성공 시resolve()에 전달되는 결과의 타입을 제네릭으로 전달한다.
(reject()에 전달되는 값은 관계 없음)

const fetchData = (): Promise<string> => {
  return new Promise((resolve, reject) => {
    const success = true;
    if (success) {
      resolve('data fetch complete');
    } else {
      reject(new Error('something went wrong'));
    }
  });
};

// Promise 체인 방식
fetchData() //
  .then(console.log)
  .catch(console.error);

// async / await 방식
async function doFetch() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (error: unknown) {
    if (error instanceof Error) {
      console.error(error.message);
    }
  }
}
doFetch();

Promise 체인 방식 vs. async / await 방식

Promise 체인 방식

  • 비동기 작업을 .then()과 .catch()로 연결하여 처리

  • 단점

    • 중첩된 비동기 작업이 많아질 경우 콜백 지옥과 유사한 복잡한 코드 구조를 초래할 수 있음
    • 코드 흐름이 분산되어 가독성이 떨어지고, 유지보수가 어려움
    • 에러 처리 범위가 명확하지 않아 특정 단계에서의 디버깅이 까다로울 수 있음

    async / await 방식

  • async 함수 내에서 await 키워드를 사용해 비동기 작업의 결과를 동기적으로 처리하는 방식

  • 장점

    • 비동기 코드의 흐름이 동기적 코드와 유사하여 가독성이 높음
    • try...catch를 사용해 에러 처리와 비동기 작업을 분리할 수 있어 코드 구조가 명확함
    • 디버깅 시 호출 스택이 간결해져 추적 용이

모듈

모듈은 관련된 코드가 모여 있는 하나의 파일을 의미한다.
각 모듈은 자체적인 스코프를 가지며, 기본적으로 모듈 내에서 정의된 변수와 함수는 해당 모듈 내부에서만 접근할 수 있다.
모듈 간에 변수나 함수를 공유하려면 export를 통해 내보내고, 이를 import로 가져와 사용할 수 있다.

모듈이 아닌 파일 (Global Scope)

단순히 import/export 구문을 사용하지 않는 파일은 공통 스코프(Global Scope)를 가진다.
이 경우, 파일 내에서 정의된 변수나 함수가 전역적으로 노출되어 다른 파일에서도 접근 가능하다.

// fileA.ts
const moduleVar = 'I am module scoped'; // 모듈 내부에서만 접근 가능
export const exportedVar_1 = 'I am exported';
export const exportedVar_2 = 'I am exported, too';

// fileB.ts
import { exportedVar_1, exportedVar_2 as var2 } from './fileA';

console.log(exportedVar); // 'I am exported'
console.log(var2); // 'I am exported, too'
console.log(moduleVar); // Error: moduleVar is not defined

as 키워드를 이용하여 import해오는 변수 및 함수의 이름을 변경할 수 있다.


타입 선언 파일

  • .ts: 구현 코드가 담긴 파일의 확장자
  • .d.ts: 타입 정보만 딤긴 파일의 확장자

주로 외부 라이브러리 사용 시 정의되지 않은 타입을 정의하기 위해 사용된다.
일일이 정의하는 것이 번거로울 경우,
@types 네임스페이스에서 제공하는 타입 라이브러리를 설치하여 사용할 수 있다.

declare module 'lodash' {
  export function isEmpty(value: any): boolean;
}

번들러

번들러란?
웹 애플리케이션을 구성하는 asset(스크립트, 스타일시트, 이미지 등)을 모두 묶어서 최적화된 여러 파일로 만들어주는 도구

번들러를 사용하는 이유

  • 성능 최적화
    브라우저가 파일을 더 빠르게 다운로드 및 실행 가능
  • 의존성 관리
    모듈간의 의존성 관리 및 체계적 코드 구성 가능
  • 개발 편의성
    개발 과정에서 필요한 다양한 작업을 간소화

Webpack

Webpack은 정적 모듈 번들러로, 다수의 JavaScript 파일 및 리소스를 효과적으로 관리해준다.

  • 개발 시
    각 모듈을 별도로 관리하여 유지보수성과 가독성을 높인다.
  • 배포 시
    번들러를 통해 모듈을 하나의 파일 또는 여러 최적화된 파일로 결합하여 로딩 시간을 줄이고 성능을 향상시킨다.

Webpack 설치하기

npm i --save-dev webpack webpack-cli webpack-dev-server html-webpack-plugin ts-loader
  • webpack, webpack-cli

    • webpack의 핵심 모듈과 명령줄 도구를 제공한다.
    • 반드시 함께 설치해야 Webpack이 동작한다.
  • webpack-dev-server

    • 로컬 개발 환경에서 사용되며, 코드 수정 시 변경 사항을 실시간으로 확인할 수 있다.
    • 자동 새로고침(Hot Reload) 기능도 제공한다.
  • html-webpack-plugin

    • 번들 결과물을 기반으로 HTML 파일을 생성하거나 수정해준다.
    • 이를 통해 브라우저에서 번들 결과를 바로 확인할 수 있다.
  • ts-loader

    • 타입스크립트를 자바스크립트로 트랜스파일해준다.
    • tsconfig.json 설정을 기반으로 동작한다.

webpack.config.js 파일 생성

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: './src/index.ts',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  plugins: [{ template: 'src/index.html' }],
};

scripts 지정하기

package.json 파일 내에서 scripts 지정하기

{
  //...
  "scripts": {
    "start": "webpack-dev-server --open --mode development",
    "build": "webpack --mode production"
  }
  //...
}

'Notes > TypeScript' 카테고리의 다른 글

TypeScript Chapter. 4  (1) 2024.12.08
TypeScript Chapter. 3  (0) 2024.12.07
TypeScript Chapter. 2  (1) 2024.12.07
TypeScript Chapter. 1  (1) 2024.12.05