TypeScript

MONA·2025년 8월 3일

나혼공

목록 보기
87/92

TypeScript

JavaScript의 상위 집합(Superset)으로, 정적 타입(static type)을 지원하는 언어
JavaScript 코드에 타입 시스템과 클래스 기반 객체지향 프로그래밍(OOP) 기능을 추가한 언어.

  • Microsoft에서 개발
  • .ts 확장자 사용
  • JavaScript로 컴파일되어 실행됨

왜 사용할까?

JavaScript의 한계TypeScript의 장점
동적 타입으로 인한 런타임 에러컴파일 단계에서 타입 오류를 미리 탐지
자동완성 지원 부족에디터에서 강력한 자동완성 및 인텔리센스
복잡한 프로젝트에서 구조적 제약 부족인터페이스, 제네릭, 클래스 등으로 구조화 가능

특징

  1. 정적 타입(Static Typing)

    변수나 함수의 타입을 명시하여 오류를 사전에 방지함

  let name : string = "이름";
  let age : number = 25;
  1. 인터페이스와 타입 시스템

    객체 구조를 명확히 정의하고, 정형화된 설계를 가능하게 함

interface User {
  id : number;
  name : string;
}
  1. 클래스 기반 객체지향 프로그래밍 지원

    JavaScript의 ES6+ 클래스를 확장하고, public, private, readonly같은 접근 제어자를 지원함

class Animal {
  constructor(private name: string) {}
  speak() {
    console.log(`${this.name} is speaking`);
  }
}
  1. 제네릭(Generic)

    함수나 클래스에서 유연하면서도 타입 안정성을 유지할 수 있음

function idenfity<T>(value: T) T {
  return value;
}
  1. 열거형(Enum)

    특정 값 집합을 명확하게 정의할 수 있음

enum Role {
  Admin,
  User,
  Guest
}
  1. 유틸리티 타입 제공

    Partial, Readonly, Pick, Omit 등 재사용성, 효율성을 높이는 타입 도구 제공

요약

키워드설명
type, interface타입 정의
enum열거형
class, extends클래스와 상속
public, private, protected접근 제어자
readonly읽기 전용 속성
as타입 단언 (Type Assertion)
unknown, any, never, void특수 타입
T제네릭 타입 변수
?선택적 속성 / 매개변수
!Non-null 단언

네이밍 컨벤션

  1. 기본 규칙
  • 영문자, 숫자, _, $만 사용 가능
  • 숫자로 시작 불가
  • 예약어 사용 금지
let userName = '유빈';   // ✅
let $price = 1000;       // ✅
let _id = 'abc';         // ✅
let 1stName = 'Kim';     // ❌ 숫자로 시작
let let = '예약어';       // ❌ 예약어
  1. 카멜케이스 사용
  • 변수명, 함수명 : camelCase
  • 클래스명, 타입명, 인터페이스명: PascalCase
let userAge = 25;                  // 변수
function getUserName() {}         // 함수
class UserProfile {}              // 클래스
interface UserData {}             // 인터페이스
type UserId = number | string;    // 타입 별칭

변수 선언 키워드

키워드설명
let블록 범위, 재할당 가능
const블록 범위, 재할당 불가 (변경 불가능한 것이 아님에 주의)
var함수 범위, 사용 지양 (hoisting 문제)

변수 타입 지정 방법
변수에 타입을 명시하거나, 타입 추론에 맡길 수 있음

// 명시적 타입 지정
let age: number = 1;
let name: string = '리리';
let isActive: boolean = true;

// 타입 추론 (타입 생략 시 자동 추론)
let city = 'Seoul'; // string으로 추론

자주 사용하는 타입

타입설명예시
number숫자 (정수, 실수)let age: number = 30;
string문자열let name: string = '리리';
boolean참/거짓let isValid: boolean = true;
any모든 타입 허용 (지양 권장)let value: any = 10;
unknown정체 모를 타입 (런타임까지 미정)let input: unknown;
null, undefined널 / 정의되지 않음let a: null = null;
void반환값 없음 (주로 함수에서 사용)function log(): void {}
never절대 반환되지 않음function fail(): never { throw new Error(); }
object객체let user: object = { name: '유빈' };
array배열let nums: number[] = [1, 2, 3];
tuple고정된 타입/길이 배열let tuple: [string, number] = ['리리', 1];
enum열거형enum Role { User, Admin }
union여러 타입 허용`let id: numberstring = 'abc';`
literal특정 값만 허용`let yes: 'Y''N' = 'Y';`

주의할 것

  • 초기화 없이 선언 시 타입 지정 필수
  • 객체 변수 타입 지정
let user: { name: string; age: number } = {
  name: '리리',
  age: 1
};
  • 배열 타입
let scores: number[] = [100, 90, 80];
let names: Array<string> = ['리리', '키키'];

실습해보기

ts-node, tsx

실습해보려 코드를 몇 줄 짜고 출력해보았는데

npx ts-node test-1.ts

아무것도 출력되지 않았다.

한참동안 헤메다가 결국 tsx를 사용하는 방법을 찾았다.
왜 ts-node는 안됐고, tsx는 됐던걸까?

항목ts-nodetsx
실행 방식TypeScript → JS → 실행 (VM 기반)ESBuild 기반 즉시 실행 (빠름 + 간단)
출력 처리 방식내부적으로 process.stdout.write() 사용표준 Node 실행처럼 console.log 직접 처리
Node 최신 버전 대응다소 느림, 버그 있음매우 빠름, 최신 Node 대응 우수
stdout 버그있음 (특히 Node 18~22 + zsh 조합)없음 (stdout 버그 거의 없음)

ts-node는 내부적으로 다음과 같이 작동한다.
1. TypeScript를 런타임에서 JavaScript로 변환
2. JS 코드를 Node.js VM (가상머신 컨텍스트) 내에서 실행
3. 출력은 process.stdout.write() 등을 통해 간접적으로 출력됨

-> 이 방법이 최신 Node.js의 스트림 처리 방식과 가끔 충돌하는 경우가 있다고 한다.

특히 mac에서 zsh, 로제타, 터미널 환경 설정 등이 함께 얽히면 출력 자체가 블로킹되거나 버퍼에 남아 표시되지 않는 문제가 발생할 수 있다.

tsx 설치하기

npm install -g tsx

실행

npx tsx test-1.ts

ts-node는 삭제해주었다.

npm uninstall -g ts-node

다시 돌아와서 찐 실습

실습

  1. 기본 타입과 변수 선언하기
// test-1.ts
// 가본 타입, 변수 선언하기

let username: string = "리리";
let age: number = 1;
let isMember: boolean;
let anyTest: any;

isMember = true;
anyTest = 123;
anyTest = { key: "value" };

console.log(username, age, isMember);
console.log("test : ", anyTest);

// 출력

리리 1 true
test :  { key: 'value' }
  1. 함수와 타입
  • 두 숫자를 더하는 함수 add(a:number, b:number): number 작성하기
  • 선택적 매개변수를 포함한 함수 logMessage(msg: string, user?: string)작성하기
function add(a: number, b: number): number {
  return a + b;
}

function logMessage(msg: string, user?: string): void {
  if (user) {
    console.log(`${user} syas : ${msg}`);
  } else {
    console.log(`someone says ${msg}`);
  }
}

console.log("result : ", add(3, 8));
logMessage("먀옹", "리리");
logMessage("거 개 짖는 소리 좀 안 나게 해라");

// 출력

result :  11
리리 syas : 먀옹
someone says 거 개 짖는 소리 좀 안 나게 해라
  1. 인터페이스
  • Product 인터페이스 정의하기.
    • 필드) id:number, title:string, price:number
    • User 인터페이스를 받아 인사 메시지를 출력하는 함수 작성하기
interface Product {
  id: number;
  title: string;
  price: number;
}

interface User {
  id: number;
  name: string;
}

function logined(user: User): void {
  console.log(`${user.name}님이 로그인하셨습니다.`);
}

const user: User = { id: 1, name: "리리" };
logined(user);

// 출력

리리님이 로그인하셨습니다.
  1. 클래스와 접근 제어자
  • Car 클래스를 만들고 model, year, drive() 메서드 정의하기
  • Employee 클래스에서 private salary 속성 정의하기
class Car {
  model: string;
  year: number;

  constructor(model: string, year: number) {
    this.model = model;
    this.year = year;
  }

  drive(): void {
    console.log(`${this.model} ${this.year} is driving`);
  }
}

class Employee {
  private salary: number;

  constructor(salary: number) {
    this.salary = salary;
  }

  getSalary(): number {
    return this.salary;
  }
}

const car = new Car("Tesla", 2025);
car.drive();

const emp = new Employee(5000);
console.log("salary is : ", emp.getSalary());

// 출력

Tesla 2025 is driving
salary is :  5000
  1. 제네릭
  • 배열의 첫 번째 요소를 반환하는 함수 getFirstElement<T>(arr: T[]): T 작성하기
  • Stack<T> 클래스를 만들어 push, pop 메서드 구현하기
function getFristElement<T>(arr: T[]): T {
  return arr[0];
}

class Stack<T> {
  private items: T[] = [];

  push(item: T): void {
    this.items.push(item);
  }

  pop(): T | undefined {
    return this.items.pop();
  }

  size(): number {
    return this.items.length;
  }
}

const numbers = [1, 2, 3];
console.log(getFristElement(numbers));

const stack = new Stack<String>();
stack.push("a");
stack.push("b");
console.log("pop :", stack.pop());
console.log("size : ", stack.size());

// 출력

1
pop : b
size :  1
  1. 유니언 타입 & 타입 가드
  • 숫자 또는 문자열을 받아서, 문자열이면 대문자로 변환/숫자면 제곱 값을 반환하는 함수 작성하기

function func1(value: string | number): string | number {
  if (typeof value === "string") {
    return value.toLocaleUpperCase();
  } else {
    return value * value;
  }
}

console.log(func1("abcde"));
console.log(func1(3));


// 출력

ABCDE
9
  1. 열거형 (Enum)

요일을 enum으로 정의하고, 해당 요일이 주말이면 "쉬세요!" 평일이면 "일해요!"를 출력하는 함수를 작성하기


enum days {
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday,
  Sunday,
}

function getMsg(day: days): string {
  switch (day) {
    case days.Sunday:
    case days.Saturday:
      return "쉬세요!";
    default:
      return "일해요!";
  }
}

console.log(getMsg(days.Sunday));
console.log(getMsg(days.Monday));


// 출력

쉬세요!
일해요!
profile
고민고민고민

0개의 댓글