typescript- interface

현우.·2024년 9월 30일

typescript

목록 보기
5/5
post-thumbnail

type

Type의 용도

  1. 특정 값이나 객체의 값에 대한 타입을 지정해줄 수 있다.
  2. Type alias(타입에 대한 별명)를 만들어줄 수 있다.

3. 타입을 특정한 값을 가지도록 제한할 수도 있다.

type Team = "blue" | "yellow" | "red";
type Health = 1 | 5 | 10;

// type선언시 특정값들로 제한할 수 있다.
type Player={
  nickName:string,
  team:Team,
  health: Health,
}

interface

오로지 객체의 형태를 ts에게 설명해주기 위한 용도

interface Player {
nickName:string,
team:Team,
health: Health,

}

const player1 :Player ={
nickName: 'hw',
team:'blue', // 특정 값중에서만 가능,
health:5,
}

type과 interface의 차이점

동일한 interface 여러개 생성

interface는 여러개의 같은 interface를 만들고 하나로 합칠 수 있다.
이때 합치는건 ts가 자동으로 수행한다.

// interface
interface User {
readonly name: string,
}
interface User {
lastName: string,
}
interface User {
health: number,
}
interface Player extends User{
}

const player1 : Player ={
name: 'hw',
lastName:'kim',
health: 10,
}

type은 여러개의 같은 type을 만들 수 없다!

// type
type User= {
name: string,
}
type User={    // error
    lastName:'kim',
}

type Player = User &{
}
const player : Player= {
name: 'hw'
}

& 는 객체지향에서의 extends 같은 느낌으로 type에서 사용된다.

추상 클래스를 대체하는 interface와 type

추상 클래스

추상클래스는 인스턴스 생성이 불가하며 추상클래스에서 명시한 추상메소드들은
추상클래스를 상속하는 클래스에서 구현해야한다.
추상 클래스를 만드는 이유는 사용할 property와 method를 명시해주기 때문이다.

abstract class User{
  constructor(
      protected firstName:string,
      protected lastName:string,
  ){}
  abstract sayHi(name:string):string;
  abstract fullName():string;
}

class Player extends User {

  sayHi(name:string) {
    return `hi ${name}. My name is ${this.fullName()}`
  }
  fullName(){
    return `${this.firstName} ${this.lastName}`;
  }
}

문제점 : ts에서 추상클래스를 만들어서 js로 컴파일될때 기본 클래스로 바뀌기 때문에 구분하기가 어렵다.

우리는 추상 클래스를 사용하는 대신 js로 컴파일시 보이지 않는 interface, type를 사용할 수 있다.

interface로 대체

interface User{
    firstName:string,
    lastName:string,
    sayHi(name:string):string
    fullName():string
}
interface Human{
    health: string,
 }


class Player implements User,Human{
    constructor(
        public firstName :string,
        public lastName:string,
        public health :string,
    ){}
    sayHi(name:string) {
    	return `hi ${name}. My name is ${this.fullName()}`
    }
    fullName(){
    	return `${this.firstName} ${this.lastName}`;
    }
}

type으로 대체

type User={
    firstName:string,
    lastName:string,
    sayHi(name:string):string
    fullName():string
}
type Human={
    health: string,
 }


class Player implements User,Human{
    constructor(
        public firstName :string,
        public lastName:string,
        public health :string,
    ){}
    sayHi(name:string) {
    	return `hi ${name}. My name is ${this.fullName()}`
    }
    fullName(){
    	return `${this.firstName} ${this.lastName}`;
    }
}

정리

  1. 클래스는 interface,type 둘다 상속 가능하며 interface,type 둘다 추상 클래스를 대체할 수 있다.
  2. 그러나 interface,type을 상속시 public property만 사용할 수 있다는 문제점이 있다.
  3. interface와 type은 객체의 형태(클래스의 형태)를 지정해준다는 점에서 동일하지만
    일반적으로 interface는 보통 객체의 형태를 지정할 경우에 사용하고 그 외 나머지 상황에서는 type을 사용한다.

다형성, 클래스, 인터페이스를 활용해 Localstorage API 만들어보기

interface SStorage<T> {
	[key:string] : T,
}

class LocalStorage<T> {
  private storage:SStorage<T>={}
  set(key:string,value:T){
    if(this.storage[key]){
      throw Error('에러');
  }
  this.storage[key]= value;
  }
  get(key:string):T{
  return this.storage[key];
  }
  remove(key:string){
  delete this.storage[key];
  }
  clear(){
  this.storage= {};
  }
}

// generic type을 사용해 다형성을 가짐.
const numberStorage= new LocalStorage<number>;
const stringStorage= new LocalStorage<string>;

numberStorage.set('first',1);
numberStorage.get('first');

stringStorage.set('name','hw');
stringStorage.get('name');

generic은 다른타입에 물려질 수 있다.
예를들어 클래스에서 사용한 generic type이 인터페이스의 타입으로 물려진다.

profile
학습 기록.

0개의 댓글