# ๐ŸŽˆ Typescript๋กœ ๋ธ”๋ก์ฒด์ธ ๋งŒ๋“ค๊ธฐ (nomad coders/๋…ธ๋งˆ๋“œ์ฝ”๋”)

TypeScript ๐Ÿ‘ super set of JavaScript

ํ”„๋ก ํŠธ ํ”Œ์ ํ•˜๋ฉด์„œ ๊ณต๋ถ€ํ•ด๋ณด๊ณ  ์‹ถ์—‡๋˜ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๊ฐ•์˜๋ฅผ ๋“ค์–ด๋ณด์•˜๋‹ค.

๋‚ด๊ฐ€ ๋“ค์—ˆ์„ ๋•Œ 2022๋ฒ„์ „์ด ์—†์—ˆ๋Š”๋ฐ ์ƒ๊ฒผ๋„ค..!!! ๋˜ ๋” ๋“ค์–ด๋ด์•ผ์ง€

# 1. Setting Typescript up

npm install typescript

๋ช…๋ น์–ด tsc ์ปดํŒŒ์ผ ์‹œ์ž‘

index.ts -> index.js/index.js.map ์ƒ์„ฑ

# 2. First steps with Typescript

const name = "Nicolas",
    age = 24,
    gender = "male";

const sayHi = (name, age, gender) => { // gender๋’ค์— ? ๋ถ™์ด๋ฉด ์„ ํƒ์ param!
    console.log(`Hello ${name}, you are ${age}, you are a ${gender}`)
}

sayHi(name, age); // param์ด 2๊ฐœ์ด๋ฏ€๋กœ ์ปดํŒŒ์ผ ์‹คํŒจ

export {};

# 3. Types in Typescript

const sayHi = (name:string, age:number, gender:string): string => { // param/return type ์ง€์ • ๊ฐ€๋Šฅ
    return `Hello ${name}, you are ${age}, you are a ${gender}`;
};

console.log(sayHi("Nicolas", 44, "male"));

export {};
  • tsc-watch ์ถ”๊ฐ€ (ts์ฝ”๋“œ๊ฐ€ ์ˆ˜์ •๋  ๋•Œ๋งˆ๋‹ค ์ž๋™์œผ๋กœ ์ปดํŒŒ์ผ)

  • tsconfig.json ์„ค์ • ์ˆ˜์ • (dist์— ์ปดํŒŒ์ผ๋œ ํŒŒ์ผ ์ €์žฅํ•˜๋„๋ก ๋ณ€๊ฒฝ)

# 4. Interfaces on Typescript

interface Human {
    name: string;
    age: number;
    gender: string;
}

const person = {
    name: "nicolas",
    age: 22,
    gender: "male"
};

const sayHi = (person: Human): string => {
    return `Hello ${person.name}, you are ${person.age}, you are a ${person.gender}`;
};

console.log(sayHi(person));

export {};

# 5. Classes on Typescript part One

interface๋Š” js๋กœ ์ปดํŒŒ์ผ ๋˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋Ÿฐ ๊ตฌ์กฐ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ class๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

class Human {
    public name: string;
    public age: number;
    public gender: string;
    constructor(name: string, age: number, gender?: string){ // ์ƒ์„ฑ์ž
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
}

const lynn = new Human('lynn', 18, 'female');

const sayHi = (person: Human): string => {
    return `Hello ${person.name}, you are ${person.age}, you are a ${person.gender}`;
};

console.log(sayHi(lynn));

export {};

# 6. Blockchain Creating a Block

// ๋ธ”๋ก ์ƒ์„ฑ์ž
class Block {
    public index: number;
    public hash: string;
    public previousHash: string;
    public data: string;
    public timestamp: number;
    constructor(
        index: number,
        hash: string,
        previousHash: string,
        data: string,
        timestamp: number
    ) {
       this.index = index;
       this.hash = hash;
       this.previousHash = previousHash;
       this.data = data;
       this.timestamp = timestamp; 
    }
}

// ๋ธ”๋ก ์„ ์–ธ
const genesisBlock: Block= new Block(0, "202020202020", "", "Hello", 123456);

// array ์ƒ์„ฑ
let blockchain: Block[] = [genesisBlock];

console.log(blockchain);

export {};

# - console

[
  Block {
    index: 0,
    hash: '202020202020',
    previousHash: '',    
    data: 'Hello',       
    timestamp: 123456    
  }
]

# 7. Creating a Block part Two

  • crypto-js ์„ค์น˜
npm install cryto-js
import * as CryptoJS from "crypto-js";

class Block {
    public index: number;
    public hash: string;
    public previousHash: string;
    public data: string;
    public timestamp: number;

    // Block ์„ ์–ธํ•ด์•ผ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
    sayHello = () => {return "HELLO"};

    // Block ์„ ์–ธํ•˜์ง€ ์•Š์•„๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ (static)
    static calculateBlockHash = (
        index: number,
        previousHash: string,
        timestamp: number,
        data: string
    ): string =>
        CryptoJS.SHA256(index + previousHash + timestamp + data).toString();

    constructor(
        index: number,
        hash: string,
        previousHash: string,
        data: string,
        timestamp: number
    ) {
        this.index = index;
        this.hash = hash;
        this.previousHash = previousHash;
        this.data = data;
        this.timestamp = timestamp;
    }
}

console.log(Block.calculateBlockHash(1, "111", 1234556, "heello"));

const genesisBlock: Block = new Block(0, "202020202020", "", "Hello", 123456);

let blockchain: Block[] = [genesisBlock];

const getBlockchain = (): Block[] => blockchain;
const getLatestBlock = (): Block => blockchain[blockchain.length - 1];
const getNewTimeStamp = (): number => Math.round(new Date().getTime() / 1000);

console.log(blockchain);

export { };

# 8. Creating a Block part Three

import * as CryptoJS from "crypto-js";

class Block {
    // Block ์„ ์–ธํ•˜์ง€ ์•Š์•„๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ (static)
    static calculateBlockHash = (
        index: number,
        previousHash: string,
        timestamp: number,
        data: string
    ): string =>
        CryptoJS.SHA256(index + previousHash + timestamp + data).toString();

    public index: number;
    public hash: string;
    public previousHash: string;
    public data: string;
    public timestamp: number;
    constructor(
        index: number,
        hash: string,
        previousHash: string,
        data: string,
        timestamp: number
    ) {
        this.index = index;
        this.hash = hash;
        this.previousHash = previousHash;
        this.data = data;
        this.timestamp = timestamp;
    }
}

const genesisBlock: Block = new Block(0, "202020202020", "", "Hello", 123456);

let blockchain: Block[] = [genesisBlock];

const getBlockchain = (): Block[] => blockchain;
const getLatestBlock = (): Block => blockchain[blockchain.length - 1];
const getNewTimeStamp = (): number => Math.round(new Date().getTime() / 1000);

const createNewBlock = (data: string): Block => {
    const previousBlock: Block = getLatestBlock();
    const newIndex: number = previousBlock.index + 1;
    const newTimestamp: number = getNewTimeStamp();
    const newHash: string = Block.calculateBlockHash(
        newIndex,
        previousBlock.hash,
        newTimestamp,
        data
    );
    const newBlock: Block = new Block(
        newIndex,
        newHash,
        previousBlock.hash,
        data,
        newTimestamp
    );
    return newBlock;
};

console.log(createNewBlock("hello"), createNewBlock("byebye"));

export { };

# 9~10. Validating BlockStructure

import * as CryptoJS from "crypto-js";

class Block {
    // Block ์„ ์–ธํ•˜์ง€ ์•Š์•„๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ (static)
    static calculateBlockHash = (
        index: number,
        previousHash: string,
        timestamp: number,
        data: string
    ): string =>
        CryptoJS.SHA256(index + previousHash + timestamp + data).toString();

    static validateStructure = (aBlock: Block): boolean =>
        typeof aBlock.index === "number" &&
        typeof aBlock.hash === "string" &&
        typeof aBlock.previousHash === "string" &&
        typeof aBlock.timestamp === "number" &&
        typeof aBlock.data === "string";

    public index: number;
    public hash: string;
    public previousHash: string;
    public data: string;
    public timestamp: number;
    constructor(
        index: number,
        hash: string,
        previousHash: string,
        data: string,
        timestamp: number
    ) {
        this.index = index;
        this.hash = hash;
        this.previousHash = previousHash;
        this.data = data;
        this.timestamp = timestamp;
    }
}

const genesisBlock: Block = new Block(0, "202020202020", "", "Hello", 123456);

let blockchain: Block[] = [genesisBlock];

const getBlockchain = (): Block[] => blockchain;
const getLatestBlock = (): Block => blockchain[blockchain.length - 1];
const getNewTimeStamp = (): number => Math.round(new Date().getTime() / 1000);

const createNewBlock = (data: string): Block => {
    const previousBlock: Block = getLatestBlock();
    const newIndex: number = previousBlock.index + 1;
    const newTimestamp: number = getNewTimeStamp();
    const newHash: string = Block.calculateBlockHash(
        newIndex,
        previousBlock.hash,
        newTimestamp,
        data
    );
    const newBlock: Block = new Block(
        newIndex,
        newHash,
        previousBlock.hash,
        data,
        newTimestamp
    );
    addBlock(newBlock); // block ๋„ฃ์–ด์ฃผ๊ธฐ
    return newBlock;
};

const getHashforBlock = (aBlock: Block) : string => Block.calculateBlockHash(aBlock.index, aBlock.previousHash, aBlock.timestamp, aBlock.data);

const isBlockValid = (candidateBlock: Block, previosBlock: Block): boolean => {
    if (!Block.validateStructure(candidateBlock)) {
        return false;
    } else if (previosBlock.index + 1 !== candidateBlock.index) {
        return false;
    } else if (previosBlock.hash !== candidateBlock.previousHash) {
        return false;
    } else if (getHashforBlock(candidateBlock) !== candidateBlock.hash) {
        return false;
    } else {
        return true;
    }
};

const addBlock = (candidateBlock: Block) : void => {
    if (isBlockValid(candidateBlock, getLatestBlock())) {
        blockchain.push(candidateBlock);
    }
}

createNewBlock("second block");
createNewBlock("third block");
createNewBlock("fourth block");

console.log(blockchain);

export {};

# - console

[
  Block {
    index: 0,
    hash: '202020202020',
    previousHash: '',
์˜คํ›„ 2:37:30 - File change detected. Starting incremental compilation...


์˜คํ›„ 2:37:30 - Found 0 errors. Watching for file changes.
[
  Block {
    index: 0,
    hash: '202020202020',
    previousHash: '',
    data: 'Hello',
    timestamp: 123456
  },
  Block {
    index: 1,
    hash: 'b5327d42f03b8915e52a4d8ca02c5d44d4c5118b3fc0c060a6e0f0d3684aa727',        
    previousHash: '202020202020',
    data: 'second block',
    timestamp: 1649050652
  },
  Block {
    index: 2,
    hash: 'b011cc0dc01e18934f483c55bb3e7938cfa448a81bd61cd1ed5e5d9b4c7e3d0e',        
    previousHash: 'b5327d42f03b8915e52a4d8ca02c5d44d4c5118b3fc0c060a6e0f0d3684aa727',
    data: 'third block',
    timestamp: 1649050652
  },
  Block {
    index: 3,
    hash: 'cd865384c8c942fdece88daf34b7a73ab65931bd3895e62c002b5dea05c81eab',
    previousHash: 'b011cc0dc01e18934f483c55bb3e7938cfa448a81bd61cd1ed5e5d9b4c7e3d0e',
    data: 'fourth block',
    timestamp: 1649050652
  }
]

# Reference

Typescript๋กœ ๋ธ”๋ก์ฒด์ธ ๋งŒ๋“ค๊ธฐ (opens new window)
github (opens new window)

Last Updated: 3/8/2024, 5:46:31 AM