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 |