And Brain said,
TypeScript, 불확실한 변수에 대비하라 본문
먼저, 이 포스팅은 자바스크립트에 대한 이해를 전제한다.
타입스크립트란 간단히 말해 타입 + 자바스크립트다.
자바스크립트는 React와 Node 등을 필두로 현재 가장 많이 사용하는 언어 중 하나이며 웹 브라우저에서는 대체 불가능한 언어로 자리매김하고 있다.
이렇게 많이 사용되는 자바스크립트는 여타 대부분의 인기 있는 언어들과 달리 독특한 특징을 갖고 있는데 바로 자유도가 엄청나게 높다는 점이다.
이 높은 자유도는 당신의 느슨하고 게으르게 짠 코드를 어떻게든 동작시킨다.
이는 프로젝트 규모가 커지면 커질수록 수많은 문제를 야기한다.
그리하여 등장한 것이 타입스크립트다.
stackoverflow 가장 사랑받는 언어 4위
자바스크립트를 대체하려는 시도는 많았지만 성공적이었던 것은 여태 단 한 차례도 없었었다.
하지만 타입스크립트는 이를 성공한 듯 보인다.
물론 타입스크립트는 근본(?)이 자바스크립트기 때문에 컴파일 시에 자바스크립트로 컴파일되긴 하지만 말이다.
왜 타입스크립트인가
기존 자바스크립트는 여러 가지 문제점들이 많았고 이에 사람들이 힘을 모아 개선하는 방식으로 발전되어 왔다.
그럼에도 해결되지 않은 큰 문제가 하나 있었는데 이는 자바스크립트가 동적 타입 스크립트 언어라는 점이었다.
자바스크립트를 쓰는 사람들에게 ECMAScript 줄여서 ES 문법은 익숙할 것이다.
ES 문법은 중간에 ES4가 빠져있다.
ES4에서 바로 이 자바스크립트에 그 당시 대유행이던 OOP(객체지향 프로그래밍)를 도입하여 자바스크립트를 Class 기반 정적 타입 언어로 바꾸려는 시도가 있었다.
이는 기존 자바스크립트의 근간을 흔드는 시도였고, 폐기됐다.
그럼에도 자바스크립트를 정적 타입 언어로 바꾸려는 시도는 계속됐고 이는 타입스크립트에 Babel이라는 컴파일러가 등장하고서야 해결되었다.
*Babel
자바스크립트 컴파일러인 Babel 덕분에 타입스크립트는 이전 버전의 자바스크립트로도 컴파일이 가능해져 기존 자바스크립트와 완벽하게 호환되었다.
Babel의 등장 후 타입스크립트는 빌드 전 오류를 파악할 수 있다는 장점까지 추가한 자바스크립트가 되었다.
타입스크립트를 시작하기에 앞선 두려움
첫째, 타입스크립트는 주류가 된 역사가 너무 짧다.
새로운 영역에 도전하는 것은 언제나 두려움이 뒤따른다.
역사가 짧은 만큼 언제까지 주류에 있을지 의구심이 들어서 배우지 않겠다면 말리지 않겠다.
하지만 주류에서 밀리는 것은 모든 언어가 가진 숙명이다.
둘째, 자바스크립트 최신 문법도 아직 잘 모르는데?
만약 당신이 자바스크립트를 할 줄 안다면, 타입스크립트를 할 줄 아는 것이다.
그냥 한 번 개발해 보라.
기존 자바스크립트에 최신 문법을 추가한 것을 배우나 타입스크립트를 배우나 동일하다.
결국 기존 자바스크립트에 조금 더 문법이 추가된 것이 ES 아닌가? 타입스크립트 또한 마찬가지다.
셋째, 타입스크립트는 느리지 않나?
타입스크립트가 대중화되기에 부족했던 점은 기존 자바스크립트에 비해 속도가 너무 느리다는 것이었다.
하지만 이는 esbuild의 등장으로 자바스크립트 속도와 차이가 없어졌다.
넷째, 기존 라이브러리들과 호환이 되나요?
Babel의 등장 전 타입스크립트는 기존 라이브러리들을 사용하지 못했다.
하지만 지금 타입스크립트는 기존 라이브러리들을 사용 가능하며 나아가 강력한 생태계를 가지게 됐다.
이제는 대부분의 라이브러리들이 타입스크립트로 만들어지고 있다.
자, 이제 간단하게 타입스크립트를 이용하여 블록체인을 구현해보자.
모르겠어도 한 번 따라쳐보자.
당신이 자바스크립트를 이해하고있다면 이 예제를 따라치는 것만으로도 타입스크립트에 대한 막연한 두려움이 오늘 이후로 사라질 것이다.
Node.js가 설치되어있어야한다.
typescript-blockchain/
├─ src/
│ ├─ Block.ts
│ ├─ Blockchain.ts
│ └─ index.ts
├─ package.json
└─ tsconfig.json
* 프로젝트 구조
npm init
npm install crypto-js typescript ts-node
npm install --save-dev @types/crypto-js
디렉토리에서 명령어 실행 이후 생성된 프로젝트 내에서 package.json을 수정해준다.
{
"name": "typescript-blockchain",
"version": "1.0.0",
"description": "A simple blockchain implementation using TypeScript",
"main": "index.js",
"scripts": {
"build": "tsc",
"start": "ts-node src/index.ts"
},
"dependencies": {
"crypto-js": "^4.1.1"
},
"devDependencies": {
"ts-node": "^10.4.0",
"typescript": "^4.5.5"
},
"keywords": [
"blockchain",
"typescript"
]
}
그리고 tsconfig.json 파일도 생성해준다.
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "./dist",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src"]
}
그리고 src 폴더 내에 Block.ts, Blockchain.ts, index.ts 파일을 각각 만들어주자.
//Block.ts
import * as CryptoJS from 'crypto-js';
// 블록 인터페이스 정의
export interface Block {
index: number;
previousHash: string;
timestamp: number;
data: string;
hash: string;
}
// 새 블록 생성 함수
export const createBlock = (index: number, previousHash: string, timestamp: number, data: string): Block => {
// 해시 값을 계산하는 함수
const calculateHash = (index: number, previousHash: string, timestamp: number, data: string): string => {
// 인덱스, 이전 해시, 타임스탬프, 데이터를 조합하여 SHA256 해시를 계산하고 문자열로 변환
return CryptoJS.SHA256(index + previousHash + timestamp + data).toString();
};
// 블록의 해시 값을 계산
const hash = calculateHash(index, previousHash, timestamp, data);
// 생성된 블록 반환
return {
index,
previousHash,
timestamp,
data,
hash,
}
}
// Blockchain.ts
import { Block, createBlock } from './Block';
// 초기 블록체인 생성 함수
export const createBlockchain = (): Block[] => {
// 제네시스(최초) 블록 생성
const genesisBlock: Block = createBlock(0, '0', Date.now(), 'Genesis Block');
// 제네시스 블록을 포함한 블록체인 반환
return [genesisBlock];
};
// 블록체인에 블록 추가 함수
export const addBlock = (blockchain: Block[], data: string): Block[] => {
// 새 블록 생성
const newBlock = createBlock(
blockchain[blockchain.length - 1].index + 1,
blockchain[blockchain.length - 1].hash,
Date.now(),
data,
);
// 기존 블록체인에 새 블록 추가 후 반환
return [...blockchain, newBlock];
};
// 블록체인의 유효성 검사 함수
export const isValidChain = (blockchain: Block[]): boolean => {
// 블록체인의 모든 블록에 대해 검사
for (let i = 1; i < blockchain.length; i++) {
// 이전 블록의 해시와 현재 블록의 previousHash 값이 일치하지 않으면 블록체인이 유효하지 않음
if (blockchain[i].previousHash !== blockchain[i - 1].hash) {
return false;
}
}
// 모든 블록이 유효하면 true 반환
return true;
};
// index.ts
import { createBlockchain, addBlock, isValidChain } from './Blockchain';
const main = (): void => {
const myBlockchain = createBlockchain();
console.log('초기 블록체인:', myBlockchain);
const updatedBlockchain = addBlock(myBlockchain, '새 블록 데이터');
console.log('새 블록 추가 후 블록체인:', updatedBlockchain);
const isValid = isValidChain(updatedBlockchain);
console.log('업데이트된 블록체인이 유효한가?', isValid);
};
main();
자, 이제 준비는 끝났고 아래 명령어를 실행시켜보자.
npm run build
npm run start
초기 블록체인: [
{
index: 0,
previousHash: '0',
timestamp: 1678891679217,
data: 'Genesis Block',
hash: '8e4ef3a855570c9c96b6998a3f5c2b6e2ff36353142c67cecfa5816e882c89f0'
}
]
새 블록 추가 후 블록체인: [
{
index: 0,
previousHash: '0',
timestamp: 1678891679217,
data: 'Genesis Block',
hash: '8e4ef3a855570c9c96b6998a3f5c2b6e2ff36353142c67cecfa5816e882c89f0'
},
{
index: 1,
previousHash: '8e4ef3a855570c9c96b6998a3f5c2b6e2ff36353142c67cecfa5816e882c89f0',
timestamp: 1678891679219,
data: '새 블록 데이터',
hash: '87f803dd2501e1bf4a336d361364458e0ac0cd07a3760b3d4857903afbb3c408'
}
]
업데이트된 블록체인이 유효한가? true
이런 형태의 콘솔이 나온다면 성공이다.
이렇게 간단하게 블록체인까지 만들어보았다.
자바스크립트에 대한 이해도에 자바나 혹은 C언어같은 언어에 대한 이해도까지 같이 갖추고 있다면 이 타입스크립트가 단순히 타입+자바스크립트일 뿐인 간단한 언어라는 것을 눈치챌 수 있을 것이다.
마지막으로, 타입스크립트는 현재 시대의 흐름이다.
현시점 가장 사랑받는 언어 중 하나지만 흘러가서 사라질 언어일지 아니면 롱런할 언어일지 아무도 모른다.
하지만 자바스크립트 진영에게 Babel이 필수인 이 시점에서 타입스크립트를 안 쓸 이유는 없다.
타입스크립트는 새로운 언어가 아니다.
자바스크립트의 매력에 타입을 곁들인, 에러방지와 생산성 향상을 추가한 자바스크립트 최신 문법일 뿐이다.
아직도 꺼려진다면, 당신의 프로젝트 일부에만 적용해 보자.
자바스크립트와 완벽하게 호환되므로 일부만 적용해도 전혀 문제 되지 않는다.
타입스크립트에 익숙해지기만이라도 하는 것은 당신에게 최소한 마이너스가 되진 않을 것이다.
여러분도 타입스크립트를 통해 불확실한 변수에 대비하도록 하자.
Thanks for watching, Have a nice day.
'IT > TypeScript' 카테고리의 다른 글
TypeScript, Function | Call Signature, Overloading 그리고 Polymorphism (0) | 2022.12.25 |
---|---|
예절을 배운 JavaScript, 'TypeScript' (1) | 2022.11.11 |
정장입은 JavaScript, 'TypeScript' (2) | 2022.11.09 |