[TypeScript] 열거형, 타입 별칭, 타입 추론, 클래스

hyxoo·2023년 5월 31일
0

코드스테이츠

목록 보기
36/37
post-thumbnail

📌 TypeScript의 열거형(Enum)

열거형은 특정 값의 집합을 정의할 때 사용된다. JavaScript와 달리 TypeScript에서는 문자형 열거형과 숫자형 열거형을 사용할 수 있다.

✔️ 기본적인 열거형

enum Color {
  Red,
  Green,
  Blue,
}

✔️ 숫자형 열거형

열거형은 숫자형과 문자열형, 혹은 이 둘의 조합으로 정의될 수 있다. 디폴트 값으로 숫자형을 사용하며 각 값은 자동으로 0부터 시작하여 1씩 증가하고, 물론 수동으로 값을 지정할 수도 있다.

// 숫자형 열거형 선언
enum Color {
  Red = 1,
  Green = 2,
  Blue = 4,
}

// 사용
let c: Color = Color.Green;
let greenValue: number = Color.Green;
let blueValue: number = Color.Blue;

console.log(c);          // 2
console.log(greenValue);  // 2
console.log(blueValue);   // 4

❗️ 역 매핑 (Reverse mappings)

역 매핑은 숫자형에서만 사용 가능하다. 열거형의 키(key)로 값(value)을 얻을 수 있고 값(value)으로 키(key)를 얻을 수도 있다.

enum Enum {
    A
}
let a = Enum.A;
let nameOfA = Enum[a]; // "A"

✔️ 문자형 열거형

문자형 열거형은 열거형의 값을 전부 다 특정 문자 또는 다른 열거형 값으로 초기화해야 하는 타입이다.

// 문자형 열거형 선언
enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT",
}

let myDirection: Direction = Direction.Up;
console.log(myDirection); // 출력: "UP"

📌 TypeScript의 인터페이스(Interface)

TypeScript에서 인터페이스(Interface)는 일반적으로 타입 체크를 위해 사용이 됩니다. 인터페이스는 변수, 함수, 클래스에 사용할 수 있으며, 인터페이스에 선언된 프로퍼티 또는 메서드의 구현을 강제하여 일관성을 유지하도록 합니다. JavaScript는 인터페이스를 따로 지원하지 않지만, TypeScript는 인터페이스를 지원합니다. TypeScript의 예약어인 interface를 사용하여 TypeScript 인터페이스를 생성할 수 있습니다.

❓ 예약어(reserved word)란

컴퓨터 프로그래밍 언어에서 이미 문법적인 용도로 사용되고 있기 때문에 식별자로 사용할 수 없는 단어를 의미한다. 예를 들어 return, import, const, let 등이 있으며, 이런 단어들은 함수의 이름이나 변수의 이름으로 사용할 수 없다.

✔️ 기본적인 인터페이스

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

// 사용
const user: User = {
	name: "anna",
	age: 20
}

인터페이스를 사용할 때는 프로퍼티의 순서를 지키지 않아도 정상적으로 선언되지만, 프로퍼티의 개수는 똑같이 가져와야 한다.

✔️ 인터페이스의 상속

인터페이스도 클래스처럼 extends라는 키워드를 사용하여 기존에 존재하던 인터페이스를 상속해 확장이 가능하다.

interface Person {
    name: string;
    age: number;
}

interface Developer extends Person {
    language: string;
}

const person: Developer = {
    language: "TypeScript",
    age: 20,
    name: "Anna",
}

여러 인터페이스를 상속할 수도 있다.

interface FoodStuff {
    name: string;
}

interface FoodAmount {
    amount: number;
}

interface FoodFreshness extends FoodStuff, FoodAmount {
	   isFreshed: boolean;
}

const food = {} as FoodFreshness;

food.name = "egg";
food.amount = 2;
food.isFreshed = true;

📌 타입 별칭(Type Aliases)

타입 별칭(Type Aliases)은 타입의 새로운 이름을 만드는 것을 말한다. 이는 새로운 이름으로 기존의 타입을 참조하는 것을 의미한다. 타입 별칭을 사용할 때는 키워드 type을 사용하여 작성한다.

type Person = {
  id: number;
  name: string;
  phone: string;
}

// Commentary 인터페이스에서 Person 타입을 참조.
interface Commentary {
  id: number;
  content: string;
  user: Person;
}

// 사용
let comment1: Commentary = {
    id: 1,
    content: "안녕하세요",
    user: {
        id: 1,
        name: "송혜수",
        phone: "000-0000-0000",
    },
}

❗️인터페이스와 타입의 차이점

타입 별칭은 말 그대로 타입에 새로운 이름을 부여하는 것에서 그치기 때문에 확장이 되지 않는다. 그러나 인터페이스는 확장이 가능하다. 인터페이스는 기존의 인터페이스 및 타입 별칭으로 만들어진 타입 둘 다 상속할 수 있기 때문에, 유연한 코드 작성을 위해서는 인터페이스로 만들어서 필요할 때마다 확장할 수 있다.

📌 타입 추론(Type Inference)

타입 추론(Type Inference)은 변수나 함수의 타입을 선언하지 않아도 TypeScript가 자동으로 유추하는 기능이다.

✔️ 기본적인 타입 추론

변수를 선언하면서 123을 할당해주면 TypeScript는 자동으로 변수를 number 타입으로 추론한다.

let isNumber = 123;

✔️ 문맥상의 타이핑(Contextual Typing)

문맥상의 타이핑은 코드의 위치(문맥)를 기준으로 타입을 결정하는 것이다.

function add(a, b) {
  return a + b;
}

위의 코드의 경우, TypeScript는 매개변수 a와 b의 타입을 자동으로 추론한다. 만약 매개변수 a와 b가 모두 숫자(Number) 타입이라면, add 함수의 반환 값도 숫자(Number) 타입으로 추론된다.

❗️ 타입 추론의 장단점

  • 장점
    • 코드의 가독성 향상
    • 개발 생산성 향상
    • 오류 발견 용이성
  • 단점
    • 타입 추론이 잘못될 경우 코드 오류 발생
    • 명시적인 타입 지정이 필요한 경우가 발생

📌 TypeScript의 클래스(Class)

TypeScript의 클래스는 JavaScript의 클래스와 비슷하지만 몇 가지 추가된 기능이 있다. 예를 들어, TypeScript에서는 클래스의 속성과 메서드에 대한 타입을 명시할 수 있다.

class Person {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  greet(): void {
    console.log(`안녕하세요, 제 이름은 ${this.name}이고, ${this.age}살 입니다.`);
  }
}

// 사용
const person = new Person('Alice', 30);
person.greet(); // "안녕하세요, 제 이름은 Alice이고, 30살 입니다."

✔️ 클래스와 상속(Inheritance)

TypeScript의 클래스(class)는 인터페이스(interface)와 마찬가지로 기존에 존재하던 클래스를 extends 키워드를 사용하여 상속받고 확장하여 새로운 클래스를 만들 수 있다.

class Animal {
    move(distanceInMeters: number): void {
        console.log(`${distanceInMeters}m 이동했습니다.`);
    }
}

class Dog extends Animal {
    speak(): void {
        console.log("멍멍!");
    }
}

const dog = new Dog();
dog.move(10);
dog.speak();

❗️ public과 private, readonly

  • public: 기본적으로 클래스 내에 선언된 멤버는 외부로 공개되는 것이 디폴트 값이지만 공개된다고 명시적으로도 표시해 줄 때 public을 사용한다.
  • private: 외부에 드러내지 않을 멤버가 있다면 private 키워드로 명시해 주면 된다.
  • readonly: readonly 키워드를 사용하여 프로퍼티를 읽기 전용으로 만들 수 있다. 읽기 전용 프로퍼티들은 선언 또는 생성자에서 초기화해야 하고 값을 변경할 수 없다.
class Mydog {
    readonly name: string;
    constructor(theName: string) {
        this.name = theName;
    }
}
let gnar = new Mydog("나르");
gnar.name = "메가 나르"; // 에러
profile
hello world!

0개의 댓글