V-logue

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

발자취/Typescript

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

보그 2022. 8. 10. 01:02

Types of TS part Three

Typescript에는 매우 독특한 몇 가지 타입이 존재한다."
독특하다고 말하는 이유는 이전 2_3.ts 에서 JS에서도 쓰이는 타입을 다뤘기 때문
number , string, boolean 등...
이제부터 등장할 type은 TS에서만 존재한다. TS의 Type Checker와 잘 소통한다.
TS에서 중요한 포인트는 Type Checker와 소통하는 것이다.

"unknown"

어떤 타입인지 모르는 변수는 TS에게 어떻게 말해야 하는걸까?
이런 상황일 때는 unknown을 사용하면 된다.

let a : unknown;

위와 같이 선언하면 TS로부터 일종의 보호를 받게 된다.
어떤 작업을 하려고 할 때 이 변수의 타입을 먼저 확인하는 방식으로 보호된다.

let b = a + 1;

위와 같이 작성된 코드를 TS는 인정하지 않는다. Why ?  a : unknown 타입이기 때문
이럴 때 무엇을 해야하나면, 먼저 확인(Check)을 해야한다.

if(typeof a === "number"){
    let b = a + 1;
}

typeof a 가 number인지 if문으로 검증하는 절차를 거치면, TS가 작업을 허용한다.
어떻게 허용하는 걸까? if문 안의 { }블록에서 a의 타입은 number가 되는데 그 이유는,
코드에서 a의 타입이 number인지 먼저 확인했기 때문이다.

if(typeof a === "string"){
    let b = a.toUpperCase();
}


단독으로 a.toUpperCase()를 사용하면 TS가 거절하지만, Check한다면 허용된다.
unknown이라는 값은 변수의 타입을 미리 지정하지 못하고, 알지 못할 때 사용한다.


"void"

void는 아무것도 return하지 않는 함수를 대상으로 사용한다.

function hello(){
    console.log("x")
}

위와 같은 코드를 작성하고 ( )안에 마우스 포인터를 가져다 대면,
'hello'이(가) 선언은 되었지만 해당 값이 읽히지는 않았습니다.ts(6133) 같은 메세지가 나온다.
hello라는 함수가 void라는 뜻이다. function hello() : void;
이게 끝이다. 따로 void를 지정해줄 필요는 없다. TS가 알아서 아무것도 return하지 않는다는 것을
인식하기 때문이다. 원하면 써도 되지만 필요하지는 않다. 이게 Void다.
하지만, 아래와 같은 방식은 좀 유용하게 써먹을 수도 있는데,

const c = hello();
c.toUpperCase();

만약 위 처럼 사용한다면, 작업은 허용되지 않는데 void 타입엔 toUpperCase가 없기 때문
'void' 형식에 'toUpperCase' 속성이 없습니다. void는 비어있는 것을 말한다. 


"never"


never는 함수가 절대 return하지 않을 때 발생한다.
예를 들어 함수에서 exception(예외)이 발생할 때 never가 발생한다.

function Throw(){
    return "x"
}

만약 Throw라는 함수가 있는데 여기에다 never를 추가하면, 

function Throw() : never {
    return "x"
}

작동하지 않을 것이다. 오류가 생긴다.

'string' 형식은 'never' 형식에 할당할 수 없습니다.

function Throw() : never {
    throw new Error("xxx");
};

하지만 에러를 발생시키면 Throw() 함수 내에서 에러가 발생하지 않게 된다.
이것은 return하지 않고 오류를 발생시키는 함수로 변한다. 바로 이런 상황일 때 never를 사용한다.
또한, never는 타입이 두가지 일 수도 있는 상황에 발생할 수 있다. 

function hello(name:string|number){
    name + 1    
}

예를 들어 name + 1 이라면 작동하지 않는다. name은 string일 수도, number일 수도 있기 때문
'+' 연산자를 'string | number' 및 'number' 형식에 적용할 수 없습니다.
그래서 typeof를 사용해야 한다. 만약 typeof name이 string이라면,

function hello(name:string|number){
    if(typeof name === "string"){
        name // (parameter) name: string
    } else if(typeof name === "number"){
        name // (parameter) name: number
    } else {
        name // (parameter) name: never
    }
}

TS가 name typeof로 확인한 type의 값을 알려주고, 마지막 else인 name은 never라는 것을 보여준다.
name이 string or number이기 때문에 두 속성이 아니라면 결국 남은 것은 never가 된다.
위의 두 속성은 실행되겠지만, 마지막 never은 절대 실행되면 안된다.
가장많이 사용하는 것은 void고 그 다음은 unknown이지만 never는 거의 사용되지 않을 것이다.

Comments