2019년 05월 24일
Typescript는 프로그래밍 언어로 Javascript + Type의 합성어이다. 컴파일 시 Javascript로 변환된다.
Javascript가 유명한 건 엄격한 규칙이 없기 때문에 사용하기 쉽고, 우리가 원하는 방향으로 수정하기도 쉽다.
하지만 큰 프로젝트에서 일을 하거나 버그를 최소화하고 싶다면 위의 장점이 단점이 된다.
Typescript로 작성하면 기능 예측이 가능하며, 코드를 읽기 쉬워지게 된다.
yarn add typescript
yarn add tsc-watch --dev
yarn add crypto-js
참고 : yarn global add typescript
로 설치하는 경우, tsc-watch가 인식하지 못하는 오류가 있습니다.
tsconfig.json
Typescript => Javascript 변환할 떄 반영하는 설정
{
"compilerOptions": {
"module": "commonjs",
"target": "ES2015",
"sourceMap": true,
"outDir": "dist"
}
}
"module": "commonjs"
node.js 평범하게 import, export 한다.
"target": "ES2015"
ES5 버전으로 컴파일 한다.
"sourceMap": true
Sourcemap을 설정한다. ( Sourcemap 이란? )
"outDir": "dist"
dist 파일로 컴파일된 파일을 출력한다."include": ["src/**/*"]
컴파일 과정에서 포함할 파일 ( src 폴더 내 전체 파일 )"excude": ["node_modules"]
컴파일 과정에서 미포함 파일
tsc-watch
소스코드 수정 시 자동으로 컴파일을 진행한다.
기존 스크립트 : yarn start 시 컴파일 및 index.js를 실행한다.
{
"scripts": {
"start": "node index.js",
"prestart": "tsc"
}
}
tsc watch 스크립트 : tsc-watch가 소스코드 변경사항을 확인하여 컴파일, 실행한다.
{
"scripts": {
"start": "tsc-watch --onSuccess \" node dist/index.js\" "
}
}
단순 함수
name, gender은 문자열, age는 숫자이다. 함수의 return 타입은 string 이다.
const sayHi = (name: string, age: number, gender: string): string => {
return `Hello ${name}, you are ${age}, you are a ${gender}!`;
};
sayHi("Minhyeong", 23, "male");
export {};
Interface
오브젝트에 대한 타입을 선언 후 함수에서 인자 값 타입을 Interface Human으로 정의한다.
interface Human {
name: string;
age: number;
gender: string;
}
const sayHi = (person: Human): string => {
return `Hello ${person.name}, you are ${person.age}, you are a ${person.gender}!`;
};
const person = {
name: "Minhyeong",
age: 23,
gender: "male",
};
sayHi(person);
export {};
Class
Human 클래스를 선언하여 타입을 체크하고 객체를 생성한다.
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 min: Human = new Human("Minhyeong", 23, "male");
const sayHi = (person: Human): string => {
return `Hello ${person.name}, you are ${person.age}, you are a ${
person.gender
}!`;
};
sayHi(min);
export {};
흐름순서
import * as CryptoJS from "crypto-js";
class Block {
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, "aaaabbbbbbccccc", "", "firstBlock", 10000000);
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);
return newBlock;
};
const getHashforBlock = (aBlock: Block): string =>
Block.calculateBlockHash(
aBlock.index,
aBlock.previousHash,
aBlock.timestamp,
aBlock.data
);
const isBlockValid = (candidateBlock: Block, previousBlock: Block): boolean => {
if (!Block.validateStructure(candidateBlock)) {
return false;
} else if (previousBlock.index + 1 !== candidateBlock.index) {
return false;
} else if (previousBlock.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(getBlockchain());
export {};
Typescript를 기초도 모르는 상태로 개발할 때 “아 이러한 상황에선 이렇게 하면 되는구나”라는 식으로 진행했었다. 강의를 들어보니 내가 놓치고 지나간 부분들이 많다는 것을 알고 새롭게 배웠다. ( 블록체인의 구조도 배운 건 일석이조였다. )
Github : typechain
Reference : nomadcoders
2019년 05월 29일
## 문제 xx 회사의 2xN명의 사원들은 N명씩 두 팀으로 나눠 숫자 게임을 하려고 합니다. 두 개의 팀을 각각 A팀과 B팀이라고 하겠습니다. 숫자 게임의 규칙은 다음과 같습니다. 먼저 모든 사원이 무작위로 자연수를 하나씩 부여받습니다. 각 사원은 딱 한 번씩 경기를 합니다. 각 경기당 A팀에서 한 사원이, B팀에서 한 사원이 나와 서로의 수를 공개합니다. 그때 숫자가 큰 쪽이 승리하게 되고, 승리한 사원이 속한 팀은 승점을 1점 얻게 됩니다. 만약 숫자가 같다면 누구도 승점을 얻지 않습니다. 전체 사원들은 우선 무작위로 자연수를 하나씩 부여받았습니다. 그다음 A팀은 빠르게 출전순서를 정했고 자신들의 출전 순서를 B팀에게 공개해버렸습니다. B팀은 그것을 보고 자신들의 최종 승점을 가장 높이는 방법으로 팀원들의 출전 순서를 정했습니다. 이때의 B팀이 얻는 승점을 구해주세요. A 팀원들이 부여받은 수가 출전 순서대로 나열되어있는 배열 A와 i번째 원소가 B팀의 i번 팀원이 부여받은 수를 의미하는 배열 B가 주어질 때, B 팀원들이 얻을 수 있는 최대 승점을 return 하도록 solution 함수를 완성해주세요. 제한사항 > A와 B의 길이는 같습니다. > A와 B의...
2019년 05월 27일
## fatal: refusing to merge unrelated histories 로컬 저장소에서 Git Repo 생성 후 push 하는 경우, 프로젝트 충돌로 나타나는 오류이다. ```bash git pull origin main --allow-unrelated-histories ```
2019년 05월 24일
1. Sourcemap 이란? 많은 개발 환경은 Webpack 등으로 빌드 과정을 거치고있다. 만일 빌드 후 취합되거나 변환 된 CSS, JavaScript 파일들이 오류가 발생한다면, 개발자 도구에서는 빌드 된 파일에서 오류를 출력하고 있을 것이다. 하지만 우리가 원하는 것은 빌드 전 오류난 파일 및 라인을 알고싶은 것이다. 예를 들면, SCSS에 오류가 있고 Webpack으로 빌드를 진행하면 웹페이지에서 오류를 알려주는 부분은 빌드가 완료된 CSS를 출력한다. JavaScript도 마찬가지로 오류가 나면 취합하고 minify된 JS를 출력하고있다. 이럴때 Soucemap을 설정하면, 코드상의 위치를 기억하고 알려주기 때문에 빌드 전 어떤 파일, 라인에서 오류가 났는지 확인할 수 있다. 2. 설정 2.1 Webpack Dev 환경에서만 작동하도록 설정하였다. { "devtool": env.mode === "development" ? "source-map" : "" } 2.2 Typescript { "compilerOptions": { "sourceMap": true } }