Photo by Jong Marshes on Unsplash
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을 사용하면 javascript의 static과 똑같이 작동한다.
type Words = {
[term:string]:string
}
class Dictionary {
praivate words: Words
constructor (
this.words: {}
) {}
static hello() {
return "hello"
}
}
Dictionary.hello();
// object의 모양 알려주기
// property의 이름은 무엇이고 그것의 타입은 뭔지 알려주기
type Player = {
nickname:string,
healthBar:number
}
// 오브젝트 만들기
// 타입평가를 위해서 mario는 Player 타입이라는걸 알려줌 -> ts보호기능 사용가능
const mario : Player = {
nickname:"mario",
healthBar:10
}
type Enemy = string;
const goomba: Enemy = "The first enemy players encounter."
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
}
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로 바꿔보기
// type Player = {
// nickname: string,
// team:Team
// health: Health
// }
interface Player {
nickname: string
team:Team
health: Health
}
바꿔도 똑같이 작동함
type은 다양한 용도로 사용할 수 있다.
interface 는 오직 한가지 용도만을 가지고 있음, 바로 오브젝트의 모양을 특정해주는것 -> React에서 많이씀
정리: 타입스크립트에서 오브젝트의 모양을 특정해주는 방법 2가지
1. type a = { b:string, c:number}
2. interface a { b:string, c:number}
interface를 타입 처럼 쓰면 이렇게 됨
type은 다양한 용도로 사용가능,
interface는 오직! 오브젝트 모양을 TS에게 설명해주기 위해서만 사용되는 키워드
interface를 썼다? -> 오직 오브젝트 모양을 ts에게 설명하기 위해서임
interface User {
name:string
}
interface Player extends User{
}
const mario: Player = {
name:"mario"
}
클래스처럼 상속 할 수도 있음
type User = {
name:string
}
type Player = User &{
}
const mario: Player = {
name:"mario"
}
type Player = User &{ }
&은 and 연산자임 (|는 or인것처럼)
interface User {
readonly name:string
}
interface Player extends User{
}
const mario: Player = {
name:"mario"
}
mario.name = "peach" // 에러
interface User {
name:string,
}
interface User {
lastName:string
}
interface User {
health:number
}
const mario: User = {
} //에러
같은 이름을 가진 interface에 property를 스택처럼 쌓을 수 있다.
interface -> OOP적인 디자인
type -> 유연한 기능