TypeScript -10-

mh·2022년 5월 6일
0

TypeScript

목록 보기
10/17
post-thumbnail

Photo by Jong Marshes on Unsplash

Class에서 readonly 사용예시

type Words = {
    [key:string]:string
}

class Dictionary {
    private words: Words
    constructor() {
        this.words = {}
    }
    add(word:Word) {
        if(this.words[word.term] === undefined) {
            this.words[word.term] = word.def
            return
        }
        console.log(`이미 ${word.term}이란 단어가 있다. 수정하고 싶다면 mod를 써라`)
    }
    def(term:string) {
        if(this.words[term]) {
            console.log(this.words[term]);
            return 
        }
        console.log(`Tämä sana ei ole sanakirjassa. Tämä sana ei ole sanakirjassa. "add()" antaa sinun lisätä sanoja.`)
    }
    mod(term:string,def:string) {
        if(this.words[term]) {
            this.words[term] = def
            return
        }
        console.log(`おいおいwwwこの単語は辞書にないwww'add'を使って追加しなければならない wwwwwwwwwwwwwww`)
    }
    del(term:string) {
        if(this.words[term]) {
            delete this.words[term]
            return
        }
        console.log(`There is no word ${term}, Try add() to add a new word`)
    }

}

class Word {
    constructor(
        public term:string,
        public def:string
    ) {}
    // 자기자신도 타입으로 쓸 수 있나? -> 있네
    findByTermAndModDef(word:Word) {
        if(this.term === word.term) {
            this.def = word.def;
            console.log("새 뜻",word.def);
            console.log("새 뜻",this.def);
        }
    }
    mod(def:string) {
        if(def.length) {
            this.def = def;
        }
        console.log("공백ㄴㄴ 아무말이라도해주세요!!")
    }
    showDef() {
        console.log(this.def)
    }

}

const khajiit = new Word("Khajiit","a word for 'carpet'")

const dict = new Dictionary();

dict.add(khajiit);

class Word의 컨스트럭터를 보면 term 과 def가 public으로 설정되어있음
따라서 외부에 의해서 객체가 변경될 수 있음
ex) khajiit.def = "The rightful ruler of Skyrim"

외부에서 객체수정을 방지하고 값만 보여주고 싶다면?
-> readonly 사용

class Word {
	constructor (
  		public readonly term:string,
        public readonly def:string
  	) {}
}

khajiit.def = "The rightful ruler of Skyrim" // <-- 불가

그런데 이렇게 되면 다른 메소드들까지 사용하지 못하게 됨

TypeScript의 Static

TypeScript에서 그대로 static을 사용하면 javascript의 static과 똑같이 작동한다.

type Words = {
	[term:string]:string
}

class Dictionary {
	praivate words: Words
    constructor (
    	this.words: {}
    ) {}

	static hello() {
    	return "hello"
    }
}

Dictionary.hello();

Interface

잠깐 복습

타입의 쓰임새 1 : 오브젝트 모양 알려주기

// object의 모양 알려주기
// property의 이름은 무엇이고 그것의 타입은 뭔지 알려주기
type Player = {
    nickname:string,
    healthBar:number
}

// 오브젝트 만들기
// 타입평가를 위해서 mario는 Player 타입이라는걸 알려줌 -> ts보호기능 사용가능
const mario : Player = {
    nickname:"mario",
    healthBar:10
}

타입의 쓰임새 2 : 변수가 무슨타입인지 정해주기

type Enemy = string;

const goomba: Enemy = "The first enemy players encounter."

쓰임새 3 타입 alias로 사용하기

type Nickname = string
type HealthBar = number


type Player = {
    nickname:Nickname,
    healthBar:HealthBar
}

const mario : Player = {
    nickname:"mario",
    healthBar:10
}

type Nickname = string
type HealthBar = number
// 문자열 배열을 갖는 Friends
type Friends = Array<string>

type Player = {
    nickname:Nickname,
    healthBar:HealthBar
}

const mario : Player = {
    nickname:"mario",
    healthBar:10
}

타입을 지정된 옵션으로만 제한하기 constraint

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

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

const mario :Player = {
    nickname: "mario",
    team: "rocket", // <- 에러
    health: 5
}

Team 타입은 문자열 콘크리트 타입 red blue yellow 만 사용가능.
Health 타입은 숫자 콘크리트 타입 1 5 10 만 사용가능
옵션에 없는 "rocket"을 넣으면 다음과 같은 에러

오브젝트의 모양을 설명하는 다른 방법 interface

기존 타입 선언방식을 interface로 바꿔보기

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

interface Player {
    nickname: string
    team:Team
    health: Health
}

바꿔도 똑같이 작동함

type vs interface

type은 다양한 용도로 사용할 수 있다.
interface 는 오직 한가지 용도만을 가지고 있음, 바로 오브젝트의 모양을 특정해주는것 -> React에서 많이씀

정리: 타입스크립트에서 오브젝트의 모양을 특정해주는 방법 2가지
1. type a = { b:string, c:number}
2. interface a { b:string, c:number}

interface를 타입 처럼 쓰면 이렇게 됨

type은 다양한 용도로 사용가능,
interface는 오직! 오브젝트 모양을 TS에게 설명해주기 위해서만 사용되는 키워드

interface를 썼다? -> 오직 오브젝트 모양을 ts에게 설명하기 위해서임

class처럼 다룰 수 있는 Interface (객체지향적인 interface)

interface User {
    name:string
}

interface Player extends User{
}

const mario: Player = {
    name:"mario"
}

클래스처럼 상속 할 수도 있음

같은 작업을 type으로 해보기

type User = {
    name:string
}

type Player = User &{
}

const mario: Player = {
    name:"mario"
}

type Player = User &{ } &은 and 연산자임 (|는 or인것처럼)

interface의 특징

  • readonly 특성 추가해보기

interface User {
    readonly name:string
}

interface Player extends User{
}

const mario: Player = {
    name:"mario"
}

mario.name = "peach" // 에러
  • property 축적하기 (cue)
interface User {
    name:string,
}

interface User {
    lastName:string
}

interface User {
    health:number
}
const mario: User =  {

} //에러


같은 이름을 가진 interface에 property를 스택처럼 쌓을 수 있다.

interface -> OOP적인 디자인
type -> 유연한 기능

정리

  • class에서 protected키워드 말고도 readonly를 사용해서 접근을 제한할 수 있다.
  • interface는 오직 객체의 모양을 특정하기 위한 용도로 사용된다.
  • type은 그보다 다양하게 사용된다.
  • interface는 클래스와 유사한점이 많다(상속,문법) 좀 더 객체지향적인 프로그래밍을 할 수 있음
  • interface 내에서도 readonly 같은 키워드를 사용할 수 있음
  • interface는 여러번 같은 이름으로 선언할 수 있음 선언할때 안의 프로퍼티들은 같은이름의 interface 안에 누적 됨
profile
🤪🤪🤪🤪🤪

0개의 댓글