[TypeScript] JavaScript의 진화!!!

2025. 3. 1. 00:36·TypeScript
728x90

JavaScript의 세계

JavaScript는 1995년 Netscape의 Brendan Eich에 의해 만들어진 스크립트 언어로, 웹 브라우저에서 실행되는 코드를 작성하기 위해 탄생했다.

동적 타입, 프로토타입 기반 객체지향, 함수형 프로그래밍 패러다임을 지원하는 다중 패러다임 언어!

 

TypeScript를 소개하기 전에 JavaScript의 주요 특징을 살펴볼까?

크게 네 가지로 나눌 수 있다.

  1. 동적 타입 시스템
  2. 프로토타입 기반 객체지향
  3. 함수형 프로그래밍 지원
  4. 비동기 프로그래밍

그럼 위 특징들에 대해 하나씩 정리해보겠다.

동적 타입 시스템

변수의 타입이 런타임에 결정되고 변경될 수 있으며,

이는 유연성을 제공하지만, 예상치 못한 타입 오류를 발생시킬 수 있다.

let variable = "Hello"; // 문자열 타입
variable = 42;          // 숫자 타입으로 변경 가능
variable = true;        // 불리언 타입으로도 변경 가능

위 코드에서 볼 수 있듯이, JavaScript에서는 하나의 변수에 여러 타입의 값을 할당할 수 있다.

이 코드에서는 'variable'이라는 변수에 처음에는 문자열, 그 다음에는 숫자, 마지막에는 불리언 값을 할당했다.

JavaScript는 이러한 타입 변경을 허용하기 때문에 코드가 유연하게 작성될 수 있지만, 대규모 프로젝트에서는 이러한 유연성이 오히려 버그의 원인이 될 수 있다.

 

프로토타입 기반 객체지향

클래스 기반이 아닌 프로토타입을 통해 상속을 구현한다(ES6부터 클래스 문법 지원).

function Person(name, age) {
    this.name = name;
    this.age = age;
}

Person.prototype.greet = function() {
    return `안녕하세요, 제 이름은 ${this.name}이고 ${this.age}살입니다.`;
};

const person1 = new Person('김철수', 25);
console.log(person1.greet()); // "안녕하세요, 제 이름은 김철수이고 25살입니다."

이 코드는 JavaScript의 프로토타입 기반 객체지향 프로그래밍을 보여준다.

  • 'Person' 함수는 생성자 역할을 하며, 'prototype' 객체에 메서드를 추가하여 모든 인스턴스가 공유할 수 있게 한다.
  • 'new' 키워드로 객체를 생성하면 해당 객체는 프로토타입 체인을 통해 'greet' 메서드에 접근할 수 있다.
ES6부터는 이러한 패턴을 클래스 문법으로 더 직관적으로 표현할 수 있게 되었지만, 내부적으로는 여전히 프로토타입 기반으로 동작한다.

 

함수형 프로그래밍 지원

함수를 일급 객체로 취급하여 고차 함수, 클로저 등의 기능을 활용할 수 있다.

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

const sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 15

이 예시는 JavaScript의 함수형 프로그래밍 특성을 보여준다.

  • 'map'과 'reduce'는 고차 함수로, 함수를 인자로 받아 새로운 결과를 반환한다.
  • 'map'은 각 요소에 함수를 적용한 새 배열을 반환하고,
  • 'reduce'는 배열의 모든 요소를 하나의 값으로 축소한다.

이러한 함수형 접근 방식은 코드를 더 선언적이고 간결하게 만들어 가독성과 유지보수성을 향상시킨다.

 

비동기 프로그래밍

콜백, 프로미스, async/await 등을 통해 비동기 작업을 처리할 수 있다!!

// 프로미스를 사용한 비동기 처리
function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('데이터 로드 완료!');
        }, 2000);
    });
}

// async/await를 사용한 비동기 처리
async function displayData() {
    try {
        console.log('데이터 로딩 중...');
        const data = await fetchData();
        console.log(data);
    } catch (error) {
        console.error('에러 발생:', error);
    }
}

displayData();

이 코드는 JavaScript의 비동기 프로그래밍 패턴을 보여준다.

  • 'fetchData' 함수는 Promise를 반환하고, 2초 후에 데이터를 resolve한다.
  • displayData' 함수는 async/await 문법을 사용하여 비동기 코드를 동기 코드처럼 읽기 쉽게 작성했다.

이러한 비동기 처리 방식은 네트워크 요청, 파일 읽기, 타이머 등 시간이 걸리는 작업을 처리할 때 유용하며, 웹 애플리케이션의 반응성을 유지하는 데 중요한 역할을 한다.

 

물론 JavaScript의 매력은 필자가 느끼기에 충분하지만,

프로젝트의 규모가 커지면서, 특히 동적 타입 시스템으로 인한 예상치 못한 오류들이 자주 발생할 것이라고 생각하고, 코드의 유지보수가 어려워질 것이라고 생각이 든다.

즉, JavaScript만으로는 한계가 있다는 것이다.


TypeScript의 등장

Microsoft에서 2012년에 발표한 TypeScript는 JavaScript의 슈퍼셋(상위 집합)으로, JavaScript의 모든 기능을 포함하면서 정적 타입 시스템을 추가한 언어이다.

TypeScript는 대규모 애플리케이션 개발에서 JavaScript의 한계를 극복하기 위해 탄생했다.

 

TypeScript 코드는 TypeScript 컴파일러(tsc)를 통해 JavaScript로 변환되어 실행된다.

이 과정에서 타입 체크가 이루어지므로, 런타임 이전에 타입 관련 오류를 발견할 수 있다.

 

TypeScript의 주요 목표를 나열하자면 아래와 같다!

 

  1. JavaScript 코드의 품질과 유지보수성 향상
  2. 대규모 애플리케이션 개발 지원
  3. 개발 도구의 향상된 지원 (자동 완성, 리팩토링 등)
  4. 타입 안전성 제공 -> 필자가 개인적으로 생각하는 중요한 부분!!!!

TypeScript는 JavaScript 생태계와 완벽하게 호환되며, 기존 JavaScript 라이브러리와 함께 사용할 수 있다.

또한, 점진적 타입 시스템을 채택하여 프로젝트의 일부만 TypeScript로 전환할 수도 있다!!!

 

아래 예시코드를 살펴볼까?

// TypeScript 예시
function greet(person: string): string {
    return `Hello, ${person}!`;
}

console.log(greet("TypeScript")); // "Hello, TypeScript!"
// console.log(greet(42)); // 컴파일 오류: Argument of type 'number' is not assignable to parameter of type 'string'.

 

위 코드에서 'greet' 함수는 문자열 타입의 매개변수를 받고 문자열을 반환한다고 명시되어 있으며,

숫자를 인자로 전달하면 컴파일 시점에 오류가 발생하여 런타임 오류를 사전에 방지할 수 있다.

이처럼 TypeScript는 코드의 의도를 명확히 표현하고, 타입 관련 버그를 조기에 발견할 수 있도록 도와준다.


TypeScript vs JavaScript

TypeScript와 JavaScript는 밀접한 관계를 가지고 있지만, 몇 가지 중요한 차이점이 있다!

일단 아래와 같이 나열해보고 하나씩 파고들어가보자.

  • 정적 타입 vs 동적 타입
  • 컴파일 vs 인터프리터
  • 개발 도구 지원
  • 코드 가독성과 유지보수성

정적 타입 vs 동적 타입

TypeScript는 정적 타입 시스템을 제공하여 변수, 함수, 객체 등의 타입을 명시적으로 선언할 수 있다.

반면 JavaScript는 동적 타입 언어로, 런타임에 타입이 결정된다.

// TypeScript
let name: string = "Kim";
let age: number = 25;
let isStudent: boolean = true;

// JavaScript
let name = "Kim";      // 타입 추론에 의해 문자열로 취급됨
let age = 25;          // 타입 추론에 의해 숫자로 취급됨
let isStudent = true;  // 타입 추론에 의해 불리언으로 취급됨

TypeScript 코드에서는 변수 선언 시 타입을 명시적으로 지정하고 있다.

'name'은 문자열, 'age'는 숫자, 'isStudent'는 불리언 타입으로 선언되어 있어, 다른 타입의 값을 할당하려고 하면 컴파일 오류가 발생한다.

 

반면 JavaScript에서는 타입을 명시하지 않지만, 초기값에 따라 타입이 결정된다.

하지만 JavaScript에서는 나중에 다른 타입의 값으로 변경할 수 있어 타입 안전성이 보장되지 않는다.

 

컴파일 vs 인터프리터

TypeScript는 컴파일 언어로, 코드가 실행되기 전에 JavaScript로 변환(트랜스파일)된다. (🚨이 과정에서 타입 검사가 이루어짐🚨)

JavaScript는 인터프리터 언어로, 브라우저나 Node.js에서 직접 실행된다.

# TypeScript 코드 컴파일
tsc app.ts  # app.js 생성

# JavaScript 코드 실행
node app.js

이 명령어는 TypeScript 파일(.ts)을 JavaScript 파일(.js)로 컴파일한 후, Node.js로 실행하는 과정을 보여준다.

TypeScript 컴파일러(tsc)는 코드를 JavaScript로 변환하면서 타입 체크를 수행하고, 오류가 있으면 컴파일을 중단한다.

이런 컴파일 과정은 코드가 실행되기 전에 타입 오류를 발견할 수 있게 해주어 런타임 오류를 줄여준다.

 

개발 도구 지원

TypeScript는 풍부한 타입 정보를 바탕으로 코드 자동 완성, 리팩토링, 타입 검사 등 개발 도구의 향상된 지원을 제공한다.

JavaScript도 최신 에디터에서 좋은 지원을 받지만, 타입 정보의 부재로 인해 제한적이다.

 

코드 가독성과 유지보수성

TypeScript의 타입 시스템은 코드의 의도를 명확히 하고, 문서화 효과가 있어 코드 가독성과 유지보수성을 향상시킨다.

JavaScript는 타입 주석이 없어 코드가 간결하지만, 대규모 프로젝트에서는 이해하기 어려울 수 있다.


TypeScript의 주요 기능들 간단히 살펴보기

크게 기능들을 5개로 나눌 수 있다.

  1. 인터페이스(Interfaces) : 인터페이스는 객체의 구조를 정의하는 방법으로, 타입 체크를 위한 강력한 도구이다.
  2. 제네릭(Generics) : 제네릭은 타입을 파라미터화하여 재사용 가능한 컴포넌트를 만들 수 있게 해준다.
  3. 열거형(Enums) : 열거형은 명명된 상수 집합을 정의하는 방법으로, 관련된 값들을 그룹화하고 가독성을 높인다.
  4. 타입 별칭(Type Aliases) : 타입 별칭은 기존 타입에 새로운 이름을 부여하거나, 복잡한 타입을 간결하게 표현할 수 있게 해준다.
  5. 클래스와 접근 제한자 : TypeScript는 ES6 클래스 구문을 확장하여 접근 제한자(public, private, protected)와 추상 클래스 등을 지원한다.

각 기능들에 대해서는 다음 포스팅들에서 다룰 예정이다!!!

728x90

'TypeScript' 카테고리의 다른 글

[TypeScript] 타입 별칭(Type Aliases) 개념정리  (0) 2025.03.07
[TypeScript] 열거형(Enums) 개념정리  (0) 2025.03.05
[TypeScript] 인터페이스 개념정리  (0) 2025.03.03
[TypeScript] 제네릭(Generics) 개념정리  (0) 2025.03.01
'TypeScript' 카테고리의 다른 글
  • [TypeScript] 타입 별칭(Type Aliases) 개념정리
  • [TypeScript] 열거형(Enums) 개념정리
  • [TypeScript] 인터페이스 개념정리
  • [TypeScript] 제네릭(Generics) 개념정리
프론트 개발자 김현중
프론트 개발자 김현중
👋반갑습니다 저는 나눔을 실천하는 개발자 꿈나무 김현중입니다⌨️🚀
  • 프론트 개발자 김현중
    삥구의 개발블로그
    프론트 개발자 김현중
  • 전체
    오늘
    어제
    • 분류 전체보기 (92)
      • 알고리즘 (5)
      • Swift (3)
      • 컴퓨터네트워크 (1)
      • React (38)
      • Docker (1)
      • SQL (8)
      • Database (2)
      • 배포 (1)
      • Spring (9)
      • TypeScript (5)
      • Next.js (12)
      • Git (1)
      • 회고 (1)
      • 컴퓨터그래픽스 (2)
      • Python (1)
      • Brew (1)
      • LangChain (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    javascript
    nextjs
    데이터베이스
    MySQL
    프론트엔드
    typescript
    Next.js
    frontend
    springboot
    알고리즘
    백준
    Backend
    java
    웹개발
    react
    appRouter
    database
    코딩테스트
    ReactHooks
    Spring
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.1
프론트 개발자 김현중
[TypeScript] JavaScript의 진화!!!
상단으로

티스토리툴바