CRA 4.0의 IE 로딩 에러

2021-01-18 00:00:00 +0000

오늘 회고:

CRA로 신규 프로젝트 생성 후 웹 성능 테스트를 진행하려고 하는데, IE에서 정상 로드가 되지않았다. 확인 해보니 CRA 4 버전에서 IE polyfill이 정상 적용 되지 않는 이슈가 있다. 이것으로 2시간을 허비하다니…. 안정적 사용을 위해서라면 오픈소스의 신규 버전 사용은 최대한 줄여야 할것 같다(마스터 버전은 항상 전단계로 사용해야지)

CRA 4.0 이상 버전 IE 11에서 로드 되지 않는 현상

현상: objects are not valid as a react child (found object with keys $$typeof render …) error 상세 내용:

  1. CRA 로 프로젝트 생성(create-react-app cra-project) : react-script 4.0.1
  2. react-app-polyfill 설치( yarn add react-app-polyfill) : “react-app-polyfill”: “^2.0.0”
  3. package.json 내 browserlist내 IE 11 추가:
"browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all",
      "ie 11"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version",
      "ie 11"
    ]
  }
  1. yarn start 로 실행
  2. IE내 error 발생

  • 참고:

    https://github.com/facebook/create-react-app/issues/9906


PWA

2021-01-14 00:00:00 +0000

오늘 회고:

PWA 가 IE에서는 어떻게 동작할지 확인할 필요가있어 PWA를 스터디 해 보았다. PWA는 service worker가 필요하지만 없다면 바로 화면 로직을 타도록 구현하면 IE에서도 서비스는 가능하다.(로컬 인스톨 등의 기능 확인 을 위해 추가 소스도 녹여보아야 겠다.)

PWA: ServiceWorker가 핵심인데 IE11은 지원하지 않는다.

인스톨 할 수 있고, 샘플 경로: git clone https://github.com/google-developer-training/pwa-training-labs.git

재생산하는 소스 경로: https://github.com/skandla2002/pwa_service.git


  • 참고:

    https://developers.google.com/web/ilt/pwa


Algorytm - BFS, DFS

2021-01-10 00:00:00 +0000

오늘 회고:

Algorythm 시험의 부수적 알고리즘 BFS, DFS를 구현

DFS: 깊이 탐색(BFS보다 많이 사용함)

int N = 100;
boolean[] visited = new boolean[N];
ArrayList<ArrayList<Integer>> edgeList = new ArrayList<ArrayList<Integer>>();

// ArrayList내에 값 입력

dfs(0); // 시작점 시작

public void dfs(int v){

    visited[v] = true;

    int len = edgeList.get(now).size();
    for (int i = 0 ; i < len ; i++){
        int next = edgeList.get(now).get(i);
        if(!visited[next]){
            visited[next] = true;
            dfs(next);
        }
    }
}

BFS: 너비 탐색(가중치 없는 경우 최적의 해 구현 가능)


ArrayDeque<Integer> q;



public void bfs(int v){
    q = new ArrayDeque<Integer>();
    q.offer(v);
    visited[v] = true;

    while(!q.isEmpty()){
        int now = q.poll();
        int len = edgeList.get(now).size();

        for(int i = 0 ; i < len ; i++){
            int next = edgeList.get(now).get(i);
            if(!visited[next]){
                visited[next] = true;
                bfs(next);
            }
        }

    }

}

  • 참고:

    교육


Algorytm - BackTracking

2021-01-09 00:00:00 +0000

오늘 회고:

오늘 본 모의평가에 나온 알고리즘 기초 작성

BackTracking: 특정 범위를 지정하여 탐색할때 사용함

문제:

N개의 좌 -> 우는 순서를 위 -> 아래는 점수를 나타낼때,
각 숫자의 순서와 숫자에 따른 점수가 arrData 내에 존재하면,
이때 숫자를 정렬할때 최대 점수의 합을 구하면?

순서:

  1. BackTracking 인자 선언 및 초기화: 점수 등의 포인트 / 방문 flag 배열 / 결과값 저장
// 3개의 선택을 할까 가장 큰 점수
let N = 3; // 종료지점 계속 변경
let arrData = [[0,0,0, 0], [1,2,3, 4], [4, 5, 6, 7], [7, 8, 9, 10]]; // 점수
let visited = new Array(N + 1);
let max = -1;
let ans = 0;


// 초기화
for(let v = 0; v <= 3 ; v++){
    visited[v] = false;
}

  1. BackTracking 함수 생성: 종료 조건에 리턴 및 결과 저장

// Depth
function back (depth, count) {
    <!-- console.log('ans', ans, 'depth', depth, 'count', count, N == depth); -->
    // 종료 조건
    if (N == depth) {
        if(max < count){
            ans = count;
        }
        return;
    }

    // 반복 조건
    for (let i = 1 ; i <= N; i++) {
        <!-- console.log('i', i, 'depth', depth, 'count', count); -->
        let next = i;
        <!-- visited[i] = true; // 현재 방문 지점 마킹 -->

        if (!visited[next]) {
            visited[next] = true;
            count = count + arrData[depth+1][next];
            back(depth + 1, count);
            visited[next] = false;
        }
    }
}

  1. 함수 실행

back(0, 0);

console.log('ans', ans);


  • 참고:

    교육


Algorytm - Index Tree

2021-01-08 00:00:00 +0000

오늘 회고:

어제 / 오늘 배운 알고리즘을 복습하기 위해 작성해 본다.

Index Tree: 포화 바이너리 트리 구조, 분할하여 계산할때 사용함

순서:

  1. Tree 초기화:
int[] tree = new int[4 * N + 1];
  1. leafNode Size 계산:
function findLeafSize(int N) {
    int count = 1;
    while(N > count){
        count *= 2;
    }
    return count - 1; // 처음 시작점을 찾기 위한 값으로 leafnode의 총 갯수 (ex. 3depth의 8이 아닌 7)로 리턴함
}
  1. indexTree 채우기
int leafSize = findLeafSize(N);

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());

// ...

st = new StringTokenizer(br.readLine());
for(int i = leafSize + 1 ; i <= leafSize + N ; i++){
    tree[i] = Integer.parseInt(st.nextToken());
}

function makeIndexTree (){
    for(int i = leafSize ; i > 0 ; i--){
        tree[i] = tree[i * 2] + tree[i * 2 + 1];
    }
}

  1. 조건에 따른 함수 생성: sum, update(swap)
let ans = 0;

function sum (int a, int b){
    int left = a + leafSize;
    int right = b + leafSize;

    if(a % 2 == 1) ans = ans + tree[left];
    if(b % 2 == 0) ans = ans + tree[right];

    <!-- ... 미완성 -->
}

function update(int a, int b){
    <!-- ... 미완성 -->
}


  • 참고:

    교육


PWA in ReactJS

2021-01-07 00:00:00 +0000

오늘 회고:

TF 참여로 인해 미리 공부해 둬야 할 것이 생겼다. PWA에 대해 이론만 알고 실젝 샘플도 만들어 본 적이 없어 최초 생성 해본다.

PWS in ReactJS 샘플 만들기

생성한 Repo: https://github.com/skandla2002/pwa_sample.git

순서

  1. CRA로 템플릿 생성한다.

    • create-react-app pwa-temp –template cra-template-pwa
    • 위 내용으로 실행해야 PWA 설정 가능 하다.(serviceWorkerRegistration.js
  2. 기본 React App 생성한다.

    • react-router-dom 도 설치하고 경로에 따른 컴포넌트를 2개 이상 생성한다.
    • 정상 기동 여부 확인한다.: yarn start
  3. ServiceWorker를 등록한다.

    • worker.js를 생성하여 index.html내에 직접 등록 한다.
    • index.js 내의 serviceWorker.register(); 부분 입력한다.
  4. 네트워크 환경을 offline로 변경 후 기동 화면 확인한다.

    • index.html 내에 reactjs 등이 로드 되지 않아도 되는 테그 영역을 추가 한다.(Loading 시점 등)
    • 정상적으로 offline 화면 나오는지 확인 한다.
  5. 웹 서버 에 올리고 다운로드도 가능한지 확인한다.

    • 외부 웹에 적용 후 테스트는 미진행

  • 참고:

    https://donggyu9410.medium.com/%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%A1%9C-%EB%A7%8C%EB%93%A0-%ED%8E%98%EC%9D%B4%EC%A7%80-progressive-web-app-%EC%9C%BC%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0-b97e7c330fd8 > https://blog.logrocket.com/setting-up-a-pwa-with-service-workers-and-create-react-app/


TypeScript - 5

2021-01-06 00:00:00 +0000

오늘 회고:

알고리즘 문제 풀이 중 너무 해결 되지 않는 알고리즘이 있어, 결국 22:00 포기.
이후 씻고 TypeScript 정리를 하게 되었다.
js 알고리즘을 하나 더 추가로 공부하고 자야지.

타입 스크립트 - 타입 호환성

  • 어떤 타입을 다른 타입으로 취급해도 되는지 판단하는 것
  • 타입 A가 타입 B에 할당 가능 하다 = 타입 A 가 타입 B의 서브타입(subtype) 이다.
  1. 숫자와 문자열의 타입 호환성
function func1(a: number, b: number | string) {
    const v1: number | string = a;
    const v2: number = b; // error
}
function func2(a: 1| 2) {
    const v1: 1 | 3 = a; // error
    const v2: 1 | 2 | 3 = a;
}
  1. 인터페이스의 타입 호환성
  • 값 자체의 타입 보다 값이 가진 내부 구조에 기반해서 타입 호환성 검사함(덕 타이핑, 구조적 타이핑)
  • A가 B로 할당 가능해야 할때 조건: B의 필수조건이 A에 존재 / 같은 속성 이름에 대해 A 속성이 B의 속성에 할당 가능
interface Person {
    name: string;
    age: number;
}
interface Product {
    name: string;
    age: number;
}
const person: Person = { name: 'mike', age: 23 };
const product: Product = person; // 이름 달라고 내부 구조 같아 할당 가능

// 선택 속성의 영향: 선택속성이 일반 속성보다 범위가 크므로 할당에 영향을 줌
interface Person {
    name: string;
    age?: number;
}
const person: Person = {
    name: 'mike'
}
const product: Product = person; // error person이 더 큰 범위로 할당안됨

// 선택속성이 있으면 더 큰범위임
interface Person {
    name: string;
    age: number;
}
interface Product {
    name: string;
    age?: number
}
const person: Person = {
    name:'mike'
}
const product:Product = person; // 할당 가능

// 추가 속성과 유니온 타입 영향
- 추가 속성: 집합은 작아짐
- 유니온 타입: 집합은 커짐
interface Person {
    name: string;
    age: number;
    gender: string;
}
interface Product {
    name: string;
    age: number | string;
}
const product: Product = {
    name: 'andy',
    age: 35
}
const person:Person = product;
  1. 함수의 타입 호환성
  • A가 B로 할당 가능 조건: 호출하는 시점에 문제가 없어야 할당 가능

    A의 매개변수 개수가 B의 매개변수 개수보다 적어야 함
    같은 위치의 매개변수에 대해 B의 매개변수가 A의 매개변수로 할당 가능해야 함 A의 반환값은 B의 반환값으로 할당 가능

type F1 = (a: number, b: string) => number;
type F2 = (a: number) => number;
type F3 = (a: number) => number | string;
let f1: F1 = (a, b) => 1;
let f2: F2 = a => 1;
let f3: F3 = a => 1;
f1 = f2;
f2 = f1; // error, f1이 매개변수 더 많음
f2 = f3; // error, f3이 리턴값 범위 더 넓음

// 배열의 map 메서드를 통해 살펴보는 함수의 타입 호환성
function addOne(value: number) {
    return value + 1;
}
const result = [1, 2, 3].map<number>(addOne); // 반환 가능, 제네릭 number로 매개변수 함수의 반환 타입
// (value: number, index: number, array: number[]) => number // map 함수의 매개변수와 타입으로 addOne 보다 매개변수가 더 많아 정상 할당 가능함
// 매개변수는 3개까지만 가능함(4개는 map 함수에서 전달하지 않음)
// addOne 함수의 매개변수 타입이 1 | 2 | 3이면 문제됨(map 메서드는 다른 숫자 전달 가능하기 때문)
// addOne 함수의 반환 타입이 number | string 이면 문제됨(map 메서드는 숫자 배열을 반환 하기 때문)
// => 함수의 타입 호환성은 호출하는 쪽에서 생각하면 좋다.

  • 참고: 실전리액트프로그래밍 / 이재승 지음 / 인사이트

TypeScript - 4

2021-01-05 00:00:00 +0000

오늘의 느낌:

처음 opensource 에 대해 파악하고 PR 하고 싶은 프로젝트를 발견하여 소스 분석 중이다.
해당 프로젝트가 TypeScript를 기반으로 하고 있어, 지금 공부한 것을 바탕으로 진행 하고 싶다.

타입 스크립트 - 인터페이스

  • 자바에서는 클래스를 구현하기 전에 필요한 메서드 정의하는 역할
  • 타입스크립트는 다양한 것들을 정의함
  1. 객체타입 정의
// 객체타입 정의하기
interface Person {
    name: string;
    age: number;
}

const p1: Person = {name: 'andy', age: 35};
const p2: Person = {name: 'andy', age: '35'}; // error

// 선택 속성
interface Person {
    name: string;
    age?: number;
}

// 유니온 정의시 필수적으로 age가 함께 정의 되어야 함
interface Person {
    name: string;
    age: number | undefined;
}

// 읽기 전용 속성
interface Person {
    readonly name: string;
    age?: number;
}
const p1: Person = {
    name: 'mike'
};
p1.name = 'jone'; // error

// 정의되지 않은 속성값에 대한 처리
interface Person {
    readonly name: string;
    age?: number;
}
const p1: Person = {
    name: 'mike',
    birthday: '1997-01-01' // error
};

const p2 = {
    name: 'mike',
    birthday: '1997-01-01'
}
const p3: Person = p2; // p3가 p2를 포함하는 더 큰 타입이므로 error 발생하지 않음

  1. 인터페이스로 정의하는 인덱스 타입
  • 속성 이름을 구체적으로 정의하지 않고 값의 타입만 정의하는 것(인덱스 타입)
// 인덱스 타입
interface Person {
    readonly name: string;
    age: number;
    [key: string]: string | number;
}
const p1: Person = {
    name: 'mike',
    birthday: '1997-01-01', // error 발생하지 않음
    age: '25' // error
}

// 여러개의 인덱스를 정의하는 경우
interface YearPricemap {
    [year: number]: A;
    [year: string]: B; // B는 A조건을 만족해야함
}

interface YearPriceMap {
    [year: number]: number;
    [year: string]: string | number;
}
const yearMap: YearPricemap = {};
yearMap[1998] = 1000;
yearMap[1998] = 'abc'; // error
yearMap['2000'] = 1000;
yearMap['2000'] = 'abc';

  1. 그밖에 할 수 있는 것
// 인터페이스로 함수 타입 정의
interface GetInfoText {
    (name: string, age: number): string; // 인터페이스로 함수 정의시에는 속성이름 없이 정의함
}
const getInfoText; GetInfoText = function(name, age) {
    const nameText = name.substr(0, 10);
    const ageText = age >= 35 ? 'senior' : 'junior';
    return `name: ${nameText}, age: ${ageText}`;
}

// 인터페이스 함수타입인 경우 추가 속성 입력 가능
interface GetInfoText {
    (name: string, age: number): string;
    totalCall: number; // 추가 속성 입력 가능
}
const getInfoText: GetInfoText = function (name, age) {
    getInfoText.totalCall += 1;
    console.log(`totalCall: ${getInfoText.totalCall}`);
};
getInfoText.totalCall = 0;

// 인터페이스로 클래스 구현하기
interface Person {
    name: string;
    age: number;
    isYoungerThan(age: number): boolean;
}
class SomePerson implements Person {
    name: string;
    age: number;
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
    isYoungerThan(age: number) {
        return this.age < age;
    }
}

// 인터페이스 확장하기
interface person {
    name: string;
    age: number;
}
interface Korean extends Person {
    isLiveInSeoul: boolean;
}
/*
interface Korean {
    name: string;
    age: number;
    isLiveInSeoul: boolean;
}
*/

// 여러개의 인터페이스 확장
interface Programer {
    favoritprograminglanguage: string;
}
interface Korean extends Person, Programmer {
    isLiveInSeoul: boolean;
}

// 인터페이스 합치기 - 교차타입 이용하여 하나로 합침

interface Person {
    name: string;
    age: number;
}

interface Product {
    name: string;
    price: number;
}

type PP = Person & Product;
const PP: PP = {
    name: 'a',
    age: 23,
    price: 1000
}


  • 참고: 실전리액트프로그래밍 / 이재승 지음 / 인사이트

TypeScript - 3

2021-01-04 00:00:00 +0000

오늘의 느낌:

처음 opensource 에 대해 파악하고 PR 하고 싶은 프로젝트를 발견하여 소스 분석 중이다.
해당 프로젝트가 TypeScript를 기반으로 하고 있어, 지금 공부한 것을 바탕으로 진행 하고 싶다.

타입 스크립트의 여러가지 타입 - 2

열거형 타입: enum 사용

enum Fruit {
    Apple,
    Banana,
    Melon
}
const v1: Fruit = Fruit.Apple; // Apple을 값으로 사용
const v2: Fruit.Apple | Fruit.Banana = Fruit.Banana; // Apple을 타입으로 사용

enum Fruit {
    Apple,
    Banana = 5,
    Melon
}
console.log(Melon); // 6, 명시적으로 1씩 증가함

// 열거형은 컴파일 후에도 관련 코드가 남아서 객체를 사용 할 수 있음
console.log(Fruit.Banana); // 5
console.log(Fruit['Banana']); // 5
console.log(Fruit[5]); // 'Banana'

// 열거형 타입 원소에 문자열 할당(단방향 맵핑, 이름 같은경우 충돌 이슈)
enum Lang {
    Korean = 'ko',
    English = 'en',
    Chinese = 'zh',
    Japanese = 'ja'
}

// 열거형 타입을 위한 유틸리티 함수: 테스크 코드 작성에 유리함
// - 원소 갯수 확인
function getEnumLen(enumObj: any) {
    const keys = Object.keys(enumObj);
    return keys.reduce((acc, key) => (typeof enumObj[key] === 'string' ? acc + 1 : acc))
}

// - 열거형 타입에 존재하는 값인지 검사
function isValidEnumVal(enumObj: any, val: number | string) {
    if (typeof value === 'number') {
        return !!enumObj[val];
    } else {
        return (
            Object.keys(enumObj)
                .filter(key => isNaN(number(key)))
                .find(key => enumObj[key] === val) != null
        )
    }
}

// 상수 열거형 타입: 컴파일 결과에 열거형 타입 객체 남기지 않을 수 있음
// 단, 열거형 타입을 상수로 정의하면 열거형 타입의 객체 사용 불가
const enum Fruit {
    Apple,
    Banana,
    Melon
}
const fruit: Fruit = Fruit.Apple;

const enum Lang {
    Korean = 'ko',
    English = 'en',
    Chinese = 'zh',
    Japanese = 'ja'
}

함수 타입: 매개변수 타입과 반환 타입

function getInfoText(name: string, age: number): string {
    const nameText = name.substr(0, 10);
    const ageText = age >= 35 ? 'senior' : 'junior';
    return `name: ${nameText}, age: ${ageText}`;
}
const v1: string = getInfoText('andy', 35);
const v2: string = getInfoText('andy', '35'); // error
const v3: number = getInfoText('andy', 35); // error

// 변수를 함수 타입으로 정의하기
const getinfoText: (name: string, age: number) => string = function(name, age) {
    ...
};

// 선택 매개변수: 반드시 입력하지 않아도 되는 변수
function getInfoText(name: string, age: number, lang?: string): string {
    const nameText = name.substr(0, 10);
    const ageText = age >= 35 ? 'senior' : 'junior';
    const langText = lang ? lang.substr(0, 10) : '';
    return `name: ${nameText}, age: ${ageText}, lang: ${langText}`;
}
// 선택 매개변수 오른쪽에 필수 매개변수를 정의한 코드: 컴파일 에러 발생
function getInfoText(name: string, lang?: string, age: number): string {
    ...
}
=> 오류없이 구현하려면 undefined 이용
function getInfoText(
    name: string,
    lang: string | undefined,
    age: number
): string {
    // ...
}

// 매개변수의 기본값 정의하기
function getInfoText (
    name: string,
    age: number = 15, // 기본값 15
    lang = 'korean' // 기본값 'korean'
): string {
    // ...
}

// 나머지 매개변수: 배열로 정의 할 수 있음
function getInfoText(name: string, ...rest: string[]): string {
    //...
}

// this 타입: 미정의시 기본 this는 any 타입, this는 첫번째 매개변수가 된다.
function getParam(index: number): string{
    const params = this.splt(','); // 오타지만 any type으로 컴파일 에러 발생하지 않는다.
    if ( index < 0 || param.length <= index) {
        return '';
    }
    return this.split(',')[index];
}

function getParam(this: string, index: number): string {
    const params = this.splt(','); // error
}

// 원시 타입에 메서드 추가하기: interface 이용함
interface String {
    getParam(this: string, index: number): string;
}
String.prototype.getParam = getParam;

console.log('as, 12, test'.getParam(1)); // 'as'

// 함수 오버로드
// ex) 두 매개변수가 모두 문자열이면 문자열 리턴, 숫자면 숫자 리턴, 두개가 다른 타입 입력하면 안됨

// 1) 함수 오버로드 없는 경우 - 오류
function add(x: number | string, y: number | string): number | string {
    if (typeof x === 'number' && typeof y === 'number') {
        return x + y;
    } else {
        const result = Number(x) + Number(y);
        return result.toString();
    }
}
const v: number = add(1, 2); // 매개변수 숫자, 반환도 숫자인데 타입 에러
console.log(add(1, '2')); // 타입이 다른데 에러 없음

// 2) 함수 오버로드 사용
function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: number | string, y:number | string): number | string {
    // ...
}
const v: number = add(1, 2); // 정상
console.log(add(1, '2')); // 타입 에러

// 명명된 매개변수: 이름 정의 > 타입 정의
function getInfoText({
    name,
    age = 15,
    lang
}: {
    name: string;
    age?: number;
    lang: string;
}): string {
    const nameText = name.substr(0, 10);
    ocnst ageText = age >= 35 ? 'senior' : 'junior';
    return `name: ${nameText}, age: ${ageText}, lang: ${langText}`;
}
=> 인터페이스 이용
interface Param {
    name: string;
    age?: number;
    lang?: string;
}
function getInfoText({ name, age = 15, lang }: Param): string {
    // ...
}


  • 참고: 실전리액트프로그래밍 / 이재승 지음 / 인사이트

TypeScript - 2

2021-01-03 00:00:00 +0000

오늘의 느낌:

현재 사용중인 React.js를 좀더 견고하게 만들어주는 TypeScript에 대해
이야기만 듣고 실제 사용해보지 않았었다.
이에 대해 알아보기 위해 정리를 시작한다.

생산성이 높은 이유

  • 정적 타입 언어의 코드는 타입으로 서로 연결 되어 있음
    1. 연관된 코드 간의 이동이 쉬움
    2. 리팩터링 쉬움
    3. 단축키 한번이면 IDE가 필요한 임포트 코드를 자동으로 넣어줌
    4. 함수 이름과 괄호 입력시 매개변수 종류와 반환값의 타입을 확인
    5. 객체 이름과 점을 입력시 속성값 목록 확인
    6. 철자 틀리거나 타입 오류시 IDE가 즉시 알려줌

실습 가능한 URL

http://typescriptlang.org/play

타입 스크립트의 여러가지 타입

const width: number = 123;
const isBag: boolean = false;
const message: string = 'hello';
const arrVal1: number[] = [1, 2, 3];
const arrVal2: Array<number> = [1, 2, 3];
const data: [string, number] = [message, width]; // 튜플(tuple)타입 정의

let v1: undefined = undefined;
let v2: null = null;
let v3: number | undefined = undefined; // 다른 타입과 유니온으로 자주 사용됨
v3 = 3;

let n1: 10 | 20 | 30;
n1 = 10;
n1 = 15; // error 발생
let s1: 'sing' | 'again';
s1 = 'music'; // error 발생

let val: any; // 기존에 자바스크립트 코드로 작성된 프로젝트를 타입스크립트로 포팅 하는 경우 사용
val = 123;
val = '123';
val = () => { console.log('123'); };

// void: 아무값 반환 없이 종료 되는 것
function f1(): void {
    console.log('hello');
}
// never: 항상 예외 발생해서 비정상적 종료되거나, 무한 루프때문에 종료 되지 않는 함수의 반환 되는 것
function f2(): never {
    throw new Error('new error');
}
function f3(): never {
    while(true){
        console.log('hello');
    }
}

let obj: object;
obj = { name: 'abc' };
console.log(obj.prop1); // 타입 에러, 속성정보 없을때 타입 정의하기 위해서는 인터페이스를 사용

// 교차타입 &, 유니온 타입 |
let v1: (1 | 2 | 3) & ( 2 | 3);
v1 = 3;
v1 = 1; // error

// type 키워드로 타입에 별칭 주기
type Width = number | string;
let width: Width;
width = 100;
width = '100px';


  • 참고: 실전리액트프로그래밍 / 이재승 지음 / 인사이트

TypeScript - 1

2021-01-02 00:00:00 +0000

오늘의 느낌:

현재 사용중인 React.js를 좀더 견고하게 만들어주는 TypeScript에 대해
이야기만 듣고 실제 사용해보지 않았었다.
이에 대해 알아보기 위해 정리를 시작한다.

정의

  • 자바 스크립트는 동적 타입 언어로 런타임에 결정된다.
  • 정적 타입언어(타입 스크립트)는 컴파일 타임에 결정 된다.
  • 자바스크립트의 모든 기능을 포함하면서 정적 타입을 지원하는 언어다.

동적 타입 언어

타입에 대한 고민 하지 않아도 되어 배우기 쉽다.
코드의 양이 적을때 생산성이 높다.
타입 오류가 런타임시 발견됨

정적 타입 언어

변수 선언시에 타입 고민해야 해서 동적타입언어보다 배우기 어렵다.
코드양 많을때 생산성이 높다.
타입오류가 컴파일시 발견 된다.

  • 참고: 실전리액트프로그래밍 / 이재승 지음 / 인사이트

2021년 새롭게 공부할것 정리하기(1. Markdown)

2021-01-01 00:00:00 +0000

오늘의 느낌:

2021년 마크다운 문법으로 글 작성 하려고 마크다운 문법에 대해 기초적인 내용을 정리 해 본다.

정의

  • 텍스트 기반의 마크업 언어.
  • github의 README.md로 인해 유명해짐

장단점

장점

1. 간결
2. 별도 도구 불필요
3. 텍스트 저장으로 용량 적음
4. 텍스트 파일로 버전관리시스템으로 변경 이력 관리 가능
5. 지원하는 플랫폼 다양

단점

1. 표준 없음
2. 도구따라 변환 방식/생성물 다름
3. 모든 HTML 마크업을 대신하지 못함

문법

헤더

  • 큰제목: 문서 제목
 H1
 ======
  • 작은 제목: 문서 부제목
 H2
 -----
  • 글머리: 1~6까지 지원
# H1
## H2
### H3
#### H4
##### H5
###### H6

BlockQuote

이메일에서 사용하는 > 블럭 인용 문자 사용

> first
>    > second
>    >    > third

first

second

third

목록

  • 순서있는 목록(번호) 순서 있는 목록은 숫자와 점을 사용
1. first
2. second
3. third
  1. first
  2. second
  3. third
  • 순서 없는 목록(글머리 기호: *, +, -)
* first
    + second
        - third
  • first
    • second
      • third

코드

4개의 공백 또는 하나의 탭으로 들여쓰기를 만나면 변환되기 시작하여 들여쓰지 않은 행을 만날때 까지 변환이 계속 된다.

  • 들여쓰기
// code
normal paragraph:

    code block

end code block

normal paragraph:

code block

end code block

  • 코드 블럭
    2가지 방식 사용함
  1. <pre><code>{code}</code></pre> 이용
class List {
    constructor(props){
        super(props);
    }
}
  1. 코드블럭코드(```)를 이용하는 방법
class List {
    constructor(props){
        super(props);
    }
}

수평선: <hr/>

* * *
***
*****
- - -
______________

링크

  • 참조 링크
[link keyword][id]
[id]: URL "Title Area"

// code
Link: [Google][googleLink]

[googleLink]: https://google.com "Go Google!!!"

Link: Google

  • 외부 링크
사용문법: [Title](link)

//code
구글연결: [Google](https://google.com, "google link")

구글연결: Google

  • 자동연결
일반적인 URL 혹은 이메일 주소 링크

// code
* 외부링크: <http://google.com/>
* 이메일 링크: <skandla2002@gmail.com>

강조

*text*
_text_
**text**
__text__
~~text~~

text
text
text
text
text

이미지

![Alt text](../assets/images/pic04.jpg)
![Alt text](../assets/images/pic04.jpg "Title Text: Wolf")

Alt text
Alt text

  • 사이즈 조절: <img width="" height=""></img>
<img src="../assets/images/pic04.jpg" width="400px" height="250px" title="px 크기 설정" alt="wolf">
<br/>
<img src="../assets/images/pic04.jpg" width="40%" height="30%" title="px 크기 설정" alt="wolf">

wolf
wolf

줄바꿈

3칸이상 띄어쓰기(‘ ‘)

줄바꿈을 위해서는 이렇게 한다.
바뀐줄

줄바꿈을 위해서는 이렇게 한다.
바뀐줄

MarkDown Editor:

  1. 기본은 VS code에서 사용
  2. 개발시에는 tui editor를 사용 한다.

  • 참고: https://gist.github.com/ihoneymon/652be052a0727ad59601

2020년을 마무리 하며.

2020-12-31 00:00:00 +0000

  • 2020년 새로운 개발자로 거듭나기 위해 열심히 진행해왔지만, 너무나도 부족한 한해였다.
  • 웹 개발자로 벌써 5년이 넘었지만, 한계가 분명하여, 방향을 잡지 못하고 있었다.
  • 오늘은 2020년 마지막날, 내년에는 이 블로그를 제대로 사용해 보기로 마음 먹었다.
  • 우선 이런 템플릿으로 진행하고, 조금씩 나만의 블로그를 만들어보는 2021년이 되어야 하겠다.
  • 사람들이 지금은 없으니 괜찮지만, 블로그가 커져서 다른 사람들이 많이 보기전에 이 글은 지울거다.
  • 그때를 위해 이 기록을 잠깐 남긴다.
  • 2020-12-31 Andy.

Phone

(000) 000-0000

Address

SDS East Campus
Seoul, 55555
Republic of Korea