개발 기록 남기기✍️

타입스크립트로 블록체인 만들기 (1) 본문

Front-End/TypeScript

타입스크립트로 블록체인 만들기 (1)

너해동물원 2022. 12. 5. 13:35

[강의로 이동](https://nomadcoders.co/typescript-for-beginners)


왜 Typescript인가?

Typescript타입 안정성을 가진다.

코드에 버그가 줄어들게 되며, 런타임 에러가 줄어들고 생산성도 늘어난다.

  • 런타임 에러 : 콘솔 안에서 일어나는 에러

Javascript는 매우 유연한 언어이다. 개발자를 이해하려고 해서 아무리 이상한 코드라고 해도 에러를 보여주지 않으려고 한다.

[1,2,3,4] + false
-> '1,2,3,4false'
function divide(a,b){
    return a / b
};

divide(2,2); // 1
divide("xxxxx"); // NaN

Javascript는 함수를 올바르게 사용하도록 강제하지 않는다. 매개변수의 타입이 잘못되어도, 매개변수의 갯수가 잘못되어도 실행을 막지 않고 실행하며 값을 반환한다.

심지어는 런타임 에러가 발생하게 되어도 아무런 경고를 주지 않아 개발자 뿐만 아니라 사용자까지 에러 메세지를 보게 된다.

✔️ 이 모든 문제를 Typescript는 해결할 수 있다!

✔️ TypescriptJavascript에 추가적인 구문을 추가하여 editor와의 단단한 통합을 지원한다. editor에서 초기에 오류를 잡을 수 있다.

✔️ Typescript 코드는 Javascript가 실행되는 모든 곳(브라우저, Node.js 또는 Deno 및 앱 등)에서 Javascript로 변환될 수 있다.

✔️ TypescriptJavascript를 이해하고 타입 추론(type inference)을 사용하여 추가 코드 없이도 훌륭한 도구를 제공한다.

 

Typescript가 동작하는 방법

브라우저는 Typescript를 읽을 수 없기 때문에, Javascript로 컴파일해야 한다.

Typescript가 제공하는 보호장치는 Typescript 코드가 Javascript로 변환되기 전에 코드를 먼저 확인해서 코드에 에러가 있다면, 그 코드는 Javascript로 컴파일되지 않고, 오류를 낸다.

Typescript의 에러를 통해서 변수나 함수의 타입을 어떻게 해야하는지, 입력값이 몇 개 들어가야 하는지 확인할 수 있다.

[타입스크립트 코드 테스트](https://www.typescriptlang.org/play)

 

Implicit Type vs Explicit Type

Typescript에서는 타입을 추론해준다.

let a = "hello"; // typescript에서 a의 타입이 string이라고 추론함
let b : boolean = true; // b가 boolean이어야 함을 명시적으로 말해

 

Type checker 와 소통하는 방식

  1. 타입 추론 : 변수에 값을 할당하면 알아서 타입을 지정한다.
  2. 명시적 정의 : b : boolean처럼 변수에 직접 타입을 지정한다.

 

✔️ 변수에는 타입 명시보다 타입 추론하는 것이 코드가 줄어든다. 보통 명시적 표현은 최소한으로 사용하는 것이 좋다.

✔️ 숫자로 된 배열 형식을 갖게 하고 싶을 땐, 추론보다 명시가 더 낫다. let c : number[ ] = [ ]

 

Types of Typescript

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


if(player.age && player.age < 10){
    // 실행될 함수
} // age가 undefined일 수도 있기 때문에 age가 존재한다는 조건을 추가해야 한다.

변수에 option symbol ?을 붙이면 age의 타입은 number | undefined가 된다. age는 작성해도 되고, 안해도 되는 속성이 된다.

 

Aliases

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


function playerMaker(name:string) : Player {
    return {
        name,
    }
};


const sun = playerMaker("sun");

sun.age = 12;

Type Aliases를 사용하여 객체 타입 뿐만 아니라 모든 타입에 이름을 지정할 수 있다. let 대신에 type 을 붙여서 사용 가능

함수의 argument의 타입을 지정할 수 있고, 함수가 반환(return)할 값의 타입도 지정할 수 있다.

 

✔️ 화살표 함수로 표현 가능

const playerMaker = (name : string) : Player  => ({name});
const sun = playerMaker("sun");
sun.age = 12;

 

readonly

type Age = number;
type Name = string;
type Player = {
    readonly name : Name,
    age? : Age
}

function playerMaker(name:string) : Player {
    return {
        name,
    }
};

const sun = playerMaker("sun");
sun.age = 12;
sun.name = "las"; // error


const numbers : readonly number[] = [1,2,3,4];
numbers.push(1); // error

변수 앞에 readonly를 붙여주면 해당 변수를 읽기 전용으로 만든다.

Playername=을 수정하려고 시도하면 Typescript=가 에러를 검출한다.

readonly가 있으면 최초 선언 후 수정 불가하므로, 해당 변수는 불변성을 가진다.

readonlyJavascript에서는 쓰이지 않고 Typescript에서만 사용된다.

 

Tuple

Tuple은 정해진 개수와 순서에 따라 배열을 선언한다.

최소한의 길이를 가져야 하고, 특정 위치에 특정 타입이 있어야 한다.

Tuplereadonly와 결합하여 쓸 수 있다.

Tuple 또한 Javascript에선 쓰이지 않는다.

const player : readonly [string, number, boolean] = ["sun", 1, true]

 

any

Typescript의 보호장치로부터 빠져나오고싶을 때 사용한다. 하지만, 자주 쓰지 않는 것이 좋다.

const a : any[] = [1,2,3,4];
const b : any = true;


a + b

 

unknown

해당 변수의 타입을 미리 알 수 없을 때 unknown을 사용한다.

unknown은 모든 값을 나타내며, any와 비슷하지만 any보다 더 안전하다.

unknown 값으로 작업을 수행하는 것은 합법적이지 않기 떄문에, 변수를 사용하려면 typeof로 타입을 확인하는 작업이 먼저 필요하다.

let a : unknown;
if(typeof a === 'number'){
    let b = a + 1;
}

 

void

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

함수에 return문이 없거나 해당 return 문에서 명시적 값을 반환하지 않을 때 항상 유추되는 타입이다.

보통 typescript는 함수가 아무것도 return 하지 않을 때, 자동으로 void 함수임을 인식한다.

function hello():void {
    console.log('x')
}; // void 함수

 

never

일부 함수는 값을 반환하지 않는다.

이는 함수가 예외를 throw하거나 프로그램 실행을 종료함을 의미한다.

function hello():never{
    throw new Error("xxx")
}
function hello(name : string | number){
    if(typeof name === "string"){
    name
    } else if (typeof name === "number"){
    name
    } else {
    name
// name의 타입은 string, number이기 때문에, 해당 함수의 타입은 never이다.
// never는 절대 실행되지 않는다.
    }
}