V-logue

[Typescript] 노마드코더 TypeScript로 블록체인 만들기 (2-2) 본문

발자취/Typescript

[Typescript] 노마드코더 TypeScript로 블록체인 만들기 (2-2)

보그 2022. 8. 9. 21:08

Types of TS part One

const player = {
    name : "nico"
}

const player : object = {
    name : "nico"
}

예를들어 player 중 전부 name이 있지만, 일부만 age가 있다면
player를 object라고 지정해주면, player.name했을 때 TS는 player에 name이 있는지 읽을 수 없다.
player.name 'object' 형식에 'name' 속성이 없습니다. ts(2339)

이럴 때 필요한 것이 object의 타입을 정해주는 것이다.

const player : {
    name : string,
    age : number
} = {}

첫번째 중괄호, player의 타입을 지정한다.
name은 String, age는 Number 타입을 가지는데, 하지만 여기까지 오면
TS가 불평하는데, player가 name과 age를 가지는데 player의 실제 내용이 없기 때문이다.

const player : {
    name : string,
    age : number
} = {
    name : "nico"
}

player의 실제 내용을 지정해 주고도 빨간줄이 뜨는 이유는
age를 찾지 못 했기 때문이다. 하지만, age는 Optional한 값이다.

const player : {
    name : string,
    age? : number
} = {
    name : "nico"
}

age에 ?가 들어가니, 완전히 알맞은 코드가 됐다. 이제 player를 보면

const player: {
    name: string;
    age?: number | undefined;
}


이상태가 된다. 이제 player안의 age를 불러오면,

if(player.age < 10){
    
}

위 처럼 작성하면 빨간줄이 나오면서 TS가 더이상 코드를 작성하지 못하게 멈춰준다.
player의 age는 May be , undefined일 수도 있다고 말하기 때문이다.

if(player.age && player.age < 10){
    
}

player의 age가 존재하는지(undefined) 아닌지 and로 같이 엮어야 올바른 코드가 된다.
이게바로 Optional parameter(선택적 변수)를 지정하는 방법이다. 그런데 만약 플레이어가 많아 진다면, 

const playerNico : {
    name : string,
    age? : number
} = {
    name : "nico"
}

const playerChoi : {
    name : string,
    age? : number
} = {
    name : "choi"
}

위와 같이 비슷한 코드를 여러번 작성해야 해서 비효율 적이다.
이 경우에는 Alias(별칭) 타입을 생성할 수 있다. 그렇게 해서 타입을 지정하면,

type Player = {
    name:string,
    age?:number
}
// 첫번째 문자는 대문자로, 

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

const choi : Player = {
    name : "choi",
    age : 12
}

이로서 Alias Type에 대해서 배웠다. 코드가 많을 때 재사용성을 높여준다.
여기서 age에 대한 또다른 Alias를 지정할 수 있다.

type Age = number;
type Name = String;

type Player = {
    name:Name,
    age?:Age
}

// 첫번째 문자는 대문자로, 

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

const choi : Player = {
    name : "choi",
    age : 12
}


이런 과한 재사용은 그렇게 효용적이진 못하다. 코드가 적당히 깔끔하고 명확하면 Ok
이번엔 함수의 return 값의 타입을 지정하는 방법
함수가 return하는 타입이 무엇인지 안다면, 멋진 자동완성과 더 많은 보호장치가 된다.
player의 object를 만들고, 그 결과로 player를 반환할 function 함수를 만든다.

type Age = number;
type Name = String;

type Player = {
    name : Name,
    age? : Age
}

function playerMaker(name : string){
    return {
        // name : name 을 더 짧게 만들려면
        name // 만 입력해도 된다.
    }
}

name : string => 인수의 타입을 지정하는 방법이다.
age는 지정해주지 않는데, playMaker의 인수에 age가 없기 때문
TS는 우리가 object를 return하는 것만 알고 있다. 타입이 string인 name이 들어 있는 obj
ts에게 playerMaker는 Player의 타입을 return 하고 말하고 싶다.

const Kim = playerMaker("Kim") 아무런 빨간줄 없이 잘 작동하는 모습, 하지만 Kim.age라면?
Kim.age = 12 , 작동하지 않는다. Why? PlayerMaker는 string인 name이라는 요소만 있는
object를 return하고 있기 때문이다. TS에게 어떻게 전달하냐? 함수가 return하는 타입을 다음과 같다.

function playerMaker(name : string) : Player {
    return {
        // name : name 을 더 짧게 만들려면
        name // 만 입력해도 된다.
    }
}

const Kim = playerMaker("Kim")
Kim.age = 12

TS는 이제 Kim이 Player라는 타입인걸 알고 있기 때문에 에러가 발생하지 않는다.
playerMaker가 String 타입으로 name을 받고, Player타입을 return하는 함수로
TS가 인식하게 된다.

const playMaker = (name:string) => ({
    name
})

const Choi = playMaker("Choi")
Choi.age = 12

name을 인수로 받고, name이 있는 object를 return할건데,
보다싶이 age라는 값이 인수에 없기 때문에 위에서 언급했던 에러가 또 발생한다.
playMaker가 Player를 return함수라는 것을... 위에서 언급한 것과 같다.

const playMaker = (name:string) : Player => ({name})
const Choi = playMaker("Choi")
Choi.age = 12

Player를 return 하는 함수라는 것을 선언해준다. 모두 같은 형식을 지니고 있는데,
콜론 ( : ) 이오고 그 다음 Type(Player)가 온다.

Comments