typescript - type과 interface

wj·2023년 7월 3일
0
  • public인 프로퍼티를 수정 불가능하게 만드려면 readonly 추가(js에서는 안 보임)
class Word {
    constructor(
        public readonly term:string,
        public readonly def :string
    ){}
}
//type의 데이터 타입 지정
type Nickname = string
type Health = number
//string의 배열
type Friends = Array<string>


//object의 모양을 알려주는 방식의 type
type Player = {
    // nickname:string,
    nickname:Nickname,
    // healthbar:10
    healthbar:Health
}

const woody: Player = {
    nickname: "woody",
    healthbar:10
}

//type이 string임을 알려주는 방식
type Food = string;

const kimchi:Food = "spicy"
  • type 활용 방식

    object의 모양을 정해줄 수 있고, type alias를 만들 수 있음
    특정 값을 갖도록 제한할 수 있음
    interface에 비해 활용 방식이 다양하다

//concrete 타입의 특정 값을 갖도록 설정(number, boolean도 가능)
type Team = "red" | "blue" | "yellow"
type Health = 1 | 5 | 10
// concrete 타입 적용 방식 - 모든 string이 될 수 있음
// type Team = string(type alias)

type Player = {
    nickname:string,
    team:Team
    health: Health
}

const nico:Player = {
    nickname:"whatever",
    team:"red",
    health: 1
}
type User = {
    name: string
}

//interface의 extends와 동일한 의미
type Player = User & {
}

const a : Player = {
    name: "nnname"
}
  • interfaces

    object의 모양을 특정해주기 위해서만 사용!
    typescript에게 object의 모양을 알려주는 방식 1.type, 2.interface
    (오브젝트의 모양을 알려주는 용도로는 interface 사용 추천, 객체지향 프로그래밍 개념)
    type 키워드에 비해 활용할 수 있는 방식이 적음
    class를 다루는 방식과 비슷하다
    property들을 축적시킬 수 있다

interface Players = string (불가능)
interface User {
    name: string
}

//class와 똑같은 extends 상속 방식
interface Player extends User {
}

const a : Player = {
    name: "nnname"
}
  • property 축적 (같은 interface에 다른 이름을 가진 property 축적)
    type 방식은 축적이 불가능하다
interface User {
    name: string
}

interface User {
    lastName:string
}

const player:User = {
    name:"",
    lastName:""
}
  • type 방식에서의 축적
  • 추상 클래스와 interface 사용의 차이

    -추상 클래스는 상속받는 다른 클래스가 가질 property와 메소드를 지정하도록 해줌.
    -표준화된 property와 메소드를 갖게 해주는 청사진을 만들기 위해 추상 클래스 사용

abstract class User {
    constructor(
        //protected로 설정된 property는 상속받는 클래스에서 접근 가능
        protected firstName:string,
        protected lastName:string
    ) {}
    //User클래스를 상속한다면 하위 2개의 메소드를 구현해야함
    abstract sayHi(name:string):string
    abstract fullName():string
}

// new User() - 추상 클래스는 새 인스턴스 생성 불가능

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

-추상 클래스의 경우 js로 컴파일 되어 남아있음
-interface를 사용하면 컴파일 되지 않고 사라짐

  • 추상클래스를 interface로 변환
    (컴파일된 js에서 추가적인 추상 클래스를 사용하지 않아서 파일 사이즈가 줄어듦)
  • interface 상속의 단점 :
    1) interface 내에선 constructor 사용이 불가능
    2) private property 사용이 불가능
//object나 class의 모양을 묘사
interface User {
    firstName:string,
    lastName:string
    sayHi(name:string):string
    fullName():string
}
//하나 이상의 interface 상속도 가능함
interface Human {
    health:number
}

//extend는 js로 컴파일 됨, implement는 컴파일 안되고 가볍게 작성 가능
//추상 클래스의 property를 가지도록 강제하는 방식을 implement도 동일하게 가짐
class Player implements User, Human {
    constructor(
        //public만 사용 가능
        public firstName:string,
        public lastName:string,
        public health:number
    ){}
    fullName(){
        return `${this.firstName} ${this.lastName}`
    }
    sayHi(name:string){
        return `Hello ${name}. My name is ${this.fullName()}`
    }
}

argument에 인터페이스를 사용해서 오브젝트의 모양 지정해줄 수 있음

//argument에 설정할 수도 있고
function makeUser(user:User){
    return "hi"
}

makeUser({
    firstName:"first",
    lastName:"last",
    fullName: () => "xx",
    sayHi: (name) => "string"
});
//인터페이스를 return할 수도 있음
function makeUser(user:User):User{
    //new Userr{} <- 인터페이스를 리턴할 경우 이렇게 작성할 필요 없음
    //이런 식으로 오브젝트를 리턴해주면 인터페이스를 만족시킴
    return {
    firstName:"first",
    lastName:"last",
    fullName: () => "xx",
    sayHi: (name) => "string"
}
    
}
  • type과 interface를 상속하여 추상 클래스 대체하기
type PlayerA = {
    firstName:string
}

interface PlayerB {
    firstName:string
}

//type과 interface 둘 다 implements로 상속 가능

class User implements PlayerB{
    constructor(
        public firstName:string
    ){}
}

결론: object나 class의 모양을 지정할 땐 interface를 사용하고, 나머지 상황에서는 type을 사용하자.

profile
tistory로 옮겼습니다

0개의 댓글