[TypeScript] 클래스와 제네릭

황수콩·2023년 11월 21일
0
post-thumbnail

6주차 TypeScript Study 에서는 클래스와 제네릭에 대해 배웠습니다

스터디 내용을 복습하면서 핵심 내용을 더 쉽게 정리해보았습니다

🏭 클래스

💬 클래스 정의

👩🏻‍🔧 자바스크립트

클래스 몸체에 클래스 프로퍼티를 선언할 수 없고 반드시 생성자 내부에서 클래스 프로퍼티를 선언하고 초기화

// person.js
class Person {
  constructor(name) {
    // 클래스 프로퍼티의 선언과 초기화
    this.name = name;
  }

  walk() {
    console.log(`${this.name} is walking.`);
  }
}

👩🏻‍🚀 타입스크립트

클래스 몸체에 클래스 프로퍼티를 사전 선언

// person.ts
class Person {
  // 클래스 프로퍼티를 사전 선언하여야 한다
  name: string;

  constructor(name: string) {
    // 클래스 프로퍼티수에 값을 할당
    this.name = name;
  }

  walk() {
    console.log(`${this.name} is walking.`);
  }
}

🚫 접근 제한자

접근 제한자를 명시하지 않았을 때

다른 클래스 기반 언어의 경우 : 암묵적으로 protected로 지정

TypeScript의 경우 : 접근 제한자를 생략한 클래스 프로퍼티와 메소드는 암묵적으로 public이 선언

따라서 public으로 지정하고자 하는 멤버 변수와 메소드는 접근 제한자를 생략

접근 가능성publicprotectedprivate
클래스 내부
자식 클래스 내부
클래스 인스턴스

🚛 제네릭

👀 제네릭이란?

데이터의 타입을 일반화한다(generalize)한다는 것을 뜻한다

즉, 제네릭은 선언 시점이 아니라 생성 시점에 타입을 명시하여 하나의 타입만이 아닌 다양한 타입을 사용할 수 있도록 하는 기법

function printInfo<T>(info: T): T {
	console.log(info);
	return info;
}

printInfo<number>(10);
printInfo<string>('하이');
printInfo<boolean>(true);

T는 제네릭을 선언할 때 관용적으로 사용되는 식별자로 타입 파라미터(Type parameter)라 한다

💡 제네릭을 사용하는 이유

정적 타입 언어의 경우 : 함수 또는 클래스를 정의하는 시점에 매개변수나 반환값의 타입을 선언

TypeScript 또한 정적 타입 언어이기 때문에 함수 또는 클래스를 정의하는 시점에 매개변수나 반환값의 타입을 선언 해야 한다

그런데 함수 또는 클래스를 정의하는 시점에 매개변수나 반환값의 타입을 선언하기 어려운 경우가 있기 때문에 제네릭을 사용한다

👍🏻 제네릭의 장점

  • 재사용성이 높은 함수와 클래스를 생성 가능
    • 여러 타입에서 동작이 가능 (한 번의 선언으로 다양한 타입에 재사용 가능)
  • 오류 파악 용이
    • 타입을 체크해 컴파일러가 오류를 찾을 수 있다.

🚫 제약 조건

원하지 않는 속성에 접근하는 것을 막기 위해 제네릭에 제약조건을 사용

⛔️ Constraints

특정 타입들로만 동작하는 제네릭 함수를 만들 때 사용, 제약 조건을 벗어나는 타입을 선언하면 에러가 발생

const printMessage = <T extends string | number>(message: T):T => {
    return message;
}
 
printMessage<string>("1");
printMessage<number>(1);
printMessage<boolean>(false); // error : Type 'boolean' does not satisfy the constraint 'string | number'.
  • extends 키워드로 제약조건을 걸어준다
  • Generic T에 제약 조건을 설정한다

🔑 keyof

정의한 인터페이스에 있는 key값만을 인자로 전달받겠다고 함수를 제약

interface FoodCart {
	name: string;
	price: number;
	quantity: number;
}

function getFoodCartOption<T extends keyof FoodCart>(foodOption: T): T {
	return foodOption;
}

getFoodCartOption<string>('a'); // 에러 발생
profile
@binllionaire

3개의 댓글

comment-user-thumbnail
2023년 11월 23일

접근제한자 접근제한성을 진짜 너무 깔끔하게 정리해줬네요!!! 저한테는 제네릭 개념이 조금 복잡하게 느껴졌는데, extends 랑 keyof 같은 키워드로 제네릭에 넘길 타입을 제약해주는 부분을 정말 쉽게 정리해줘서 제대로 복습해볼 수 있었어요!! 👍

답글 달기
comment-user-thumbnail
2023년 11월 24일

한눈에 딱 정리되게 핵심 개념만 잘 정리해주셔서 감사합니다!!
갑자기 궁금해졌는데 접근제한자와 접근제어가는 혼용되는 워딩인가요??
둘다 서치해봐도 같은 개념이 나오네용

답글 달기
comment-user-thumbnail
2023년 11월 24일

제네릭의 장점이 사실상 타입스크립트의 장점이기도 하네요 ㅎㅎ 깔끔하게 정리 된 글 감사합니다 !

답글 달기