Node.js와 ejs를 이용해서 pagination 구현
다음 코드를 추가해주면 모듈로 뺄 필요없이 중복된 변수명을 사용가능!
"moduleDetection": "force"
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
// }
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을 인자값으로 받는 function
import { Color } from "../types";
function printRGB(color: Color): Color {
return color;
}
// console.log(printRGB(Red)); // ㄴㄴ
console.log(printRGB(Color.Red)); //Red
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
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을 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 = {}; // ✅
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 = {}));
=> 아무것도 사용하고 있지 않지만 모두 트랜스파일이 됨
// 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만 트랜스파일됨!!
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'. -> 상수의 이름을 바꿨으니 에러가 납니다