프론트엔드/TypeScript

[TypeScript] type와 interface의 차이, class

s_omi 2024. 1. 21. 14:31
728x90
반응형
SMALL

Class

  • 추상(abstract) 클래스
    • 오직 다른 클래스가 상속받을 수 있는 클래스이지만 직접 새로운 인스턴스를 만들 수는 없다.
  • 추상(abstract) 메소드
    • 추상 클래스 내에서는 메소드를 적지 않고 call signature만 작성해야한다.
    • 추상 클래스를 상속받는 클래스들이 반드시 구현(implement)해야하는 메소드이다.
  • 접근 가능한 위치
    • private : 해당 클래스 내에서만 접근 가능, 자식 클래스에서도 접근 불가
    • protected : 해당 클래스와 자식 클래스에서 접근 가능
    • public : 기본값, 모든 클래스에서 접근 가능
  • 상속 방법 : extends
abstract class User{
	constructor(
		private firstname : string,
		private lastname : string,
		public nickname : string
	){
		abstract getNickName() : void // 추상 클래스 내이므로 call signature만 작성

		protected getFullName() {
			return `${this.firstname} ${this.lastname}`;
		}
	}
}

class Player extends User{
	getNickName(){        // 추상 메소드이므로 반드시 구현해야 한다.
		this.getFullName(); // 가능, protected이므로 
		console.log(this.nickname); // 가능, public이므로
	}
}

const user = new User("fr", "las", "ni"); // 에러, 추상 클래스의 인스턴스를 만들 수 없다.
const player = new Player("fr", "las", "ni"); 
player.getFullName() // 에러, protected이므로

 

 

type

특정 값이나 객체의 값에 대한 타입을 지정해줄 수 있다.

  • 특징
    • Type alias(타입에 대한 별명)를 만들어줄 수 있다.
    • 타입을 특정한 값을 가지도록 제한할 수 있다.
type Team = "red" | "blue" | "green"; // 특정한 값만 가지도록 설정

type Player = {
	name: string,
	team: Team
}

const first : Player = {
	name: "fi",
	team: "yellow"  // 에러, 없는 팀 이름
}

 

interface

object의 모양(형태)를 특정해주기 위한 것이다.

  • 특징
    • 상속의 개념을 사용할 수 있다.
    • 속성들을 축적시킬 수 있다.
type Team = "red" | "blue" | "green";

// typescript에게 object의 모양을 알려주는 방법 
// 1번째
type Player = {
	name: string,
	team: Team
}

// 2번째
interface Player {
	name: string,
	team: Team
}

interface Age = number; // 에러, interface는 오직 object의 모양만 가능
type User = { // 에러
	name : string
}

type User = { // 에러, 축척 불가능
	lastname : string
}

interface User2 = {
	name : string
}

interface User2 = { // 축척 가능
	lastname : string
}

// 위의 interface 2개를 합치면 
interface User2 = {
	name : string
	lastname : string
}
  • 상속 방법 : extends

 

type와 interface의 차이

=> 클래스나 오브젝트의 모양을 정의하고 싶으면 interface, 그 외의 경우에는 type

  • 상속 방법의 차이
    • type은 새 속성을 추가하기 위해 다시 선언될 수 없다.
    • interface은 항상 상속 및 축척이 가능하다.
// type 
type Animal = { 
	name : string
}

type Animal { // 에러, 같은 이름을 써서 상속 불가능
	color : string
}

type AnimalB = Animal & { // 상속 가능
	color : string
}

type Bear = Animal & { 
	honey : boolean
}

const bear = getBear();
bear.name;
bear.honey;

// interface 
interface Animal { 
	name : string
}

interface Animal { // 같은 이름을 써서 상속 가능
	color : string
}

interface Bear extends Animal { 
	honey : boolean
}

const bear = getBear();
bear.name;
bear.honey;

 

 

class의 abstract vs interface의 implements

abstract로 상속받은 클래스를 JavaScript로 변환하게 되면, abstract 코드도 JavaScript 파일에 남게 된다. 이 두 기능은 JavaScript에는 없으므로 TypeScript를 JavaScript로 변환한 코드에서 보이지 않는다.

 

그래서 코드 최적화를 위해, interface와 implements를 사용하는 것이 더 낫다.

abstract와 interface / implements는 둘 다 같은 기능을 구현한다.

// 아래의 두 코드는 같은 기능을 한다.
// class abstract
abstract class User {
	constructor(
		protected firstname : string,
		protected lastname : string
	) {}
	abstract sayHi(name : string) : string
	abstract fullName() : string
}

class Player extends User {
	fullName(){
		return `${this.firstname} ${this.lastname}`;
	}
	sayHi(name : string){
		return `Hello ${name}. My name is ${this.fullName}`;
	}
}

// interface implements
interface User {
	firstname : string,
	lastname : string,
	sayHi(name : string) : string
	fullName() : string
}

class Player implements User {
	constructor(
		public firstname : string, // interface User에서 firstname이 public이기 때문
		public lastname : string
	) {}
	fullName(){
		return `${this.firstname} ${this.lastname}`;
	}
	sayHi(name : string){
		return `Hello ${name}. My name is ${this.fullName}`;
	}
}

function makeUser(user: User) : User {
	firstname : "one",
	lastname : "two",
	sayHi(name) => "string"
	fullName() => "xx"
}
728x90
반응형
LIST