내배캠 74일차

·2023년 1월 26일
0

내일배움캠프

목록 보기
80/142
post-thumbnail

Pagination

사용한 git hub 주소

Node.js와 ejs를 이용해서 pagination 구현

typescript

사용한 git hub 주소

tsconfig.json

다음 코드를 추가해주면 모듈로 뺄 필요없이 중복된 변수명을 사용가능!

"moduleDetection": "force"

Enum(열거형)

NumberEnum

TS의 열거형은 숫자가 기본이라서 따로 값을 정의하지 않으면 0을 시작으로 기본값이 부여됨.
문자형과 다른점은 Reverse mapping이 가능하다는 점!

enum Color {
  Red = 0,
  Green,
  Blue = 9,
  Purple,
}

const myColor = Color.Red;
console.log(myColor); // 0

const yourColor = Color.Blue;
console.log(yourColor); // 2

const yourColor2: Color = Color.Blue;
console.log(yourColor2); // 2

// //안됨!
// const yourColor3: Color.Green = Color.Blue;

console.log(Color["Green"]); // 1

// Reverse mapping
console.log(Color[0]); // "Red"
console.log(Color[1]); // "Green"
console.log(Color[4]); // undefined
console.log(Color);
// {
//   '0': 'Red',
//   '1': 'Green',
//   '9': 'Blue',
//   '10': 'Purple',
//   Red: 0,
//   Green: 1,
//   Blue: 9,
//   Purple: 10
// }

StringEnum

enum을 문자형으로 쓸 땐 각 enum값을 문자열로 명시해줘야함.

import { Color } from "../types";

const myColor = Color.Red;
console.log(myColor); // "Red"

const yourColor = Color.Blue;
console.log(yourColor); // "Blue"

console.log("------------------------");

const faveColor = Color.Blue;
console.log(faveColor); // Blue

const chorock: Color = Color.Green;
console.log(chorock); // Green

// // 안됨
// const colorRed: Color = "Red"; //Color.Red라고 해줘야함!
// // typecast
// 이런식으로 타입을 부여할 수 있긴 함!
const colorRed: Color = "Red" as Color;
console.log(colorRed); // "Red"
const imposterColor: Color = "Potato" as Color;
console.log(imposterColor); // "Potato"
//그래도 사용안하는 것이 좋음

Enum 써보기

functions

enum을 인자값으로 받는 function

import { Color } from "../types";

function printRGB(color: Color): Color {
  return color;
}

// console.log(printRGB(Red)); // ㄴㄴ
console.log(printRGB(Color.Red)); //Red

interface

enum을 인자로 바로 받아볼수도 있지만 이렇게 인터페이스(interface) 나 타입(type)에 존재하는 프로퍼티에 타입으로 정의를 해서 쓰는 경우가 많다.

import { Color } from "../types";

enum Direction {
  Up = "Up",
  Down = "Down",
  Left = "Left",
  Right = "Right",
}

// interface 키워드로 타입 선언하기
interface IThingsInLife {
  colorOfPen: Color;
  keyboardArrow: Direction;
}

function printThngsInLife(things: IThingsInLife): string {
  return `color of pen: ${things.colorOfPen} keyboard arrow: ${things.keyboardArrow}`;
}

console.log(
  printThngsInLife({ colorOfPen: Color.Blue, keyboardArrow: Direction.Left })
); // color of pen: Blue keyboard arrow: Left

Object.<메소드>랑 함께 사용

enum은 객체 인스턴스의 함수 중 이 세가지 함수랑 자주 쓰입니다: Object.keys(), Object.values(), 그리고 Object.entries() 객체를 배열로 전환하는데 유용함.

import { type } from "os";
import { Color } from "./types";

const keys = Object.keys(Color);
console.log(keys); // [ 'Red', 'Green', 'Blue' ] - string[]

console.log("--------------------------------");

const values = Object.values(Color);
console.log(values); // [ 'Red', 'Green', 'Blue' ] - Color[]

console.log("--------------------------------");

const keyValues = Object.entries(Color);
console.log(keyValues); // [ [ 'Red', 'Red' ], [ 'Green', 'Green' ], [ 'Blue', 'Blue' ] ]

console.log("--------------------------------");

// enum을 key로 사용해서 인덱싱을 할 땐 interface를 사용못함
type TObjectType = {
  [key in Color]?: string;
};

const myObject: TObjectType = {};

values.forEach((key) => {
  myObject[key] = "hello";
});

console.log(myObject); // { Red: 'hello', Green: 'hello', Blue: 'hello' }

각 함수의 구조 및 시그니쳐

// Object.keys()
keys(o: object): string[];

// Object.values()
values<T>(o: { [s: string]: T } | ArrayLike<T>): T[];

// Object.entries()
entries<T>(o: { [s: string]: T } | ArrayLike<T>): [string, T][];

객체 키값을 enum으로 설정

위에서 // enum을 key로 사용해서 인덱싱을 할 땐 interface를 사용못함

// interface도 가능
type TTableData = {
  [x: string]: string;
};

// 실수를 해도 에러가 나지않아서 실수인지 알 길이 없음
const myTableData: TTableData = {
  Id: "1",
  firstName: "jane",
  lastName: "doe",
  score: "100",
  // 실수로 더해진 키/밸류값
  age: "99",
};

// tree-shaking
const enum TableKey {
  ID = "ID",
  FirstName = "firstName",
  LastName = "lastName",
  Score = "score",
}

type StrictTableData = { [key in TableKey]: string };

// // 허용되지 않는 필드가 들어가면
// const myStrictTableData1: StrictTableData = {
//   ID: "1",
//   firstName: "jane",
//   lastName: "doe",
//   score: "100",
//   age: "99", // ❌ Object literal may only specify known properties, and 'Age' does not exist in type 'StrictTableData'.
// };

// // 타입에는 있으나 추가가 되지 않을 필드가 있으면
// const myStrictTableData2: StrictTableData = {
//   // ❌ Property '[TableKey.Score]' is missing in type '{ ID: string; FirstName: string; LastName: string; }' but required in type 'StrictTableData'.
//   ID: "1",
//   firstName: "jane",
//   lastName: "doe",
// };

type LessStrictTableData = { [key in TableKey]?: string };

const lessStrictTableData: LessStrictTableData = {
  ID: "1",
}; // ✅

// 그리고 이렇게 빈 객체도 통과합니다
const emptyTableData: LessStrictTableData = {}; // ✅

Enum과 tree-shaking

Tree-shaking(트리쉐이킹)은 사용하지 않는 코드를 제거하는 기능

트리쉐이킹을 안했을 때

// index.ts
enum Color {
  Red = 'Red',
  Green = 'Green',
  Blue = 'Blue',
}

// 쓰이지 않는 enum을 트랜스파일 해보면...
// index.js
"use strict";
var Color;
(function (Color) {
    Color["Red"] = "Red";
    Color["Green"] = "Green";
    Color["Blue"] = "Blue";
})(Color || (Color = {}));

=> 아무것도 사용하고 있지 않지만 모두 트랜스파일이 됨

쓰이더라도 트리쉐이킹이 되는 enum선언 방법

// index.ts
const enum Color {
  Red = "Red",
  Green = "Green",
  Blue = "Blue",
}

const green = Color.Green;

// index.js
"use strict";
const green = "Green" /* Color.Green */;

=> 사용하는 green만 트랜스파일됨!!

Tip

enum도 분해 할당이 가능합니다. 그리고 분해 할당을 하는 동시에 분해 된 상수의 이름도 바꿀 수 있습니다.

import { Color } from "../types";

// enum도 분해 할당이 가능
const { Red, Green, Blue: ImBlue } = Color; // Blue => ImBlue변경

const green = Green; // Color.Green할 필요가 없음!
const pepper = Red;

console.log(Green); // "Green"
console.log(ImBlue); // "Blue"
// console.log(Blue); // Cannot find name 'Blue'. -> 상수의 이름을 바꿨으니 에러가 납니다
profile
개발자 꿈나무

0개의 댓글