저장을 습관화
TypeScript 연습 - 카페 관리 프로그램 만들기 본문
작업 환경: Windows 10, VSC
작업 목표: 카페 관리 프로그램 만들기
주요 기능 - 권한:
음료 등록 기능 - 어드민
음료 삭제 기능 - 어드민
음료 조회 기능 - 어드민, 고객
음료 주문 기능 - 고객
음료 준비 완료 기능 - 어드민
음료 수령 기능 - 고객
작업 기록
1. 환경 구축
$ npm init -y
$ tsc --init --rootDir ./src --outDir ./dist --esModuleInterop --module commonjs --strict true --allowJS true --checkJS true
--rootDir: 소스 파일이 들어가는 경로를 명시적으로 지정함
이번에는 ./src 디렉토리에 넣겠다고 하였음
-- outDir: 컴파일된 파일이 tsc로 되면 TS파일이 JS 파일로 나올것임
여기서는 ./dist 디렉토리에 들어가게끔 하였음
--esModuleInterop: require 구문을 사용해서 가져오던 CommonJS 방식의 모듈을 es모듈 방식의 import 구문으로 가져올 수 있게 함
package.json, tsconfig.json 파일 생성 확인
package.json 파일 내용 수정
{
...(생략)...
"scripts": {
"start": "tsc && node ./dist/index.js",
"build": "tsc --build",
"clean": "tsc --build --clean"
},
...(생략)...
}
2. /src/index.ts 폴더 생성
- /src/index.tx
interface User {
id: number;
name: string;
role: "admin" | "customer"; // union 타입
}
interface Beverage {
name: string;
price: number;
}
interface Order {
orderId: number;
customerId: number;
customerName: string;
beverageName: string;
status: "placed" | "completed" | "picked-up"; // union 타입
}
let beverages: Beverage[] = [];
let orders: Order[] = [];
function isAdmin(user: User): boolean {
return user.role === "admin";
}
function isCustomer(user: User): boolean {
return user.role === "customer";
}
// 음료 등록 API - 어드민
function addBeverage(user: User, name: string, price: number): void {
if (!isAdmin(user)) {
console.log("권한이 없습니다.");
return;
}
const newBeverage: Beverage = { name, price };
beverages.push(newBeverage);
}
// 음료 삭제 API - 어드민
function removeBeverage(user: User, beverageName: string): void {
if (!isAdmin(user)) {
console.log("권한이 없습니다.");
return;
}
beverages = beverages.filter((beverage) => beverage.name !== beverageName);
}
// 음료 조회 API - 어드민, 고객
function getBeverages(user: User): Beverage[] {
if (!user) {
return [];
}
return beverages;
}
// 음료 찾기 API - 고객, 음료 주문할 때 판매하지 않는 음료를 사는 것을 방지
function findBeverage(beverageName: string): Beverage | undefined {
return beverages.find((beverage) => beverage.name === beverageName);
}
// find 메소드의 조건 함수는 beverage라는 매개변수를 받습니다. 이 매개변수는 배열의 각 요소인 Beverage 타입의 객체를 나타냅니다. 조건 함수는 beverage.name과 beverageName을 비교하여 두 값이 일치하는지 확인합니다.
// 일치하는 음료를 찾으면 해당 음료 객체를 반환합니다. 일치하는 음료가 없으면 undefined를 반환합니다.
// 음료 주문 API - 고객
function placeOrder(user: User, beverageName: string): number {
if (!isCustomer(user)) {
console.log("권한이 없습니다.");
return -1;
}
const beverage = findBeverage(beverageName);
if (!beverage) {
console.log("해당 음료를 찾을 수 없습니다.");
return -1;
}
const newOrder: Order = {
orderId: orders.length + 1,
customerId: user.id,
customerName: user.name,
beverageName,
status: "placed",
};
orders.push(newOrder);
return newOrder.orderId;
}
// 음료 준비 완료 API - 어드민
function completeOrder(user: User, orderId: number): void {
if (!isAdmin(user)) {
console.log("권한이 없습니다.");
return;
}
const order = orders.find((order) => order.orderId === orderId);
if (order) {
order.status = "completed"; // 단순히 주문의 상태만 바꾸고 끝!
console.log(
`[고객 메시지] ${order.customerName}님~ 주문하신 ${order.beverageName} 1잔 나왔습니다~`
);
}
}
// 음료 수령 API - 고객
function pickUpOrder(user: User, orderId: number): void {
if (!isCustomer(user)) {
console.log("권한이 없습니다.");
return;
}
const order = orders.find(
(order) => order.orderId === orderId && order.customerId === user.id
);
if (order && order.status === "completed") {
order.status = "picked-up";
console.log(
`[어드민 메시지] 고객 ID[${order.customerId}]님이 주문 ID[${orderId}]을 수령했습니다.`
);
}
}
// 테스트
function main() {
const admin: User = {
id: 1,
name: "바리스타",
role: "admin",
};
// 유저 생성
const member1: User = {
id: 2,
name: "ctrs",
role: "customer",
};
const member2: User = {
id: 3,
name: "testCust",
role: "customer",
};
// 음료 등록
addBeverage(admin, "아메리카노", 4000);
addBeverage(admin, "카페라떼", 4500);
addBeverage(admin, "에스프레소", 3000);
// 음료 삭제
removeBeverage(admin, "에스프레소");
console.log(
`안녕하세요~ ${
member1.name
} 고객님! 카페에 오신 것을 환영합니다. 저희는 ${JSON.stringify(
getBeverages(member1)
)}를 판매하고 있습니다.`
);
// 음료 주문
const orderId1 = placeOrder(member1, "아메리카노");
if (orderId1 > 0) {
setTimeout(() => {
// 음료 제작 완료
completeOrder(admin, orderId1);
// 음료 수령
pickUpOrder(member1, orderId1);
}, 1000);
}
console.log(
`안녕하세요~ ${
member2.name
} 고객님! 카페에 오신 것을 환영합니다. 저희는 ${JSON.stringify(
getBeverages(member2)
)}를 판매하고 있습니다.`
);
// 음료 주문
const orderId2 = placeOrder(member2, "카페라떼");
if (orderId2 > 0) {
setTimeout(() => {
// 음료 제작 완료
completeOrder(admin, orderId2);
// 음료 수령
pickUpOrder(member2, orderId2);
}, 3000);
}
}
// 테스트 코드 실행
main();
4. 컴파일
$ npm run build
5. /dist/index.js 파일 생성 확인
"use strict";
let beverages = [];
let orders = [];
function isAdmin(user) {
return user.role === "admin";
}
function isCustomer(user) {
return user.role === "customer";
}
// 음료 등록 API - 어드민
function addBeverage(user, name, price) {
if (!isAdmin(user)) {
console.log("권한이 없습니다.");
return;
}
const newBeverage = { name, price };
beverages.push(newBeverage);
}
// 음료 삭제 API - 어드민
function removeBeverage(user, beverageName) {
if (!isAdmin(user)) {
console.log("권한이 없습니다.");
return;
}
beverages = beverages.filter((beverage) => beverage.name !== beverageName);
}
// 음료 조회 API - 어드민, 고객
function getBeverages(user) {
if (!user) {
return [];
}
return beverages;
}
// 음료 찾기 API - 고객, 음료 주문할 때 판매하지 않는 음료를 사는 것을 방지
function findBeverage(beverageName) {
return beverages.find((beverage) => beverage.name === beverageName);
}
// find 메소드의 조건 함수는 beverage라는 매개변수를 받습니다. 이 매개변수는 배열의 각 요소인 Beverage 타입의 객체를 나타냅니다. 조건 함수는 beverage.name과 beverageName을 비교하여 두 값이 일치하는지 확인합니다.
// 일치하는 음료를 찾으면 해당 음료 객체를 반환합니다. 일치하는 음료가 없으면 undefined를 반환합니다.
// 음료 주문 API - 고객
function placeOrder(user, beverageName) {
if (!isCustomer(user)) {
console.log("권한이 없습니다.");
return -1;
}
const beverage = findBeverage(beverageName);
if (!beverage) {
console.log("해당 음료를 찾을 수 없습니다.");
return -1;
}
const newOrder = {
orderId: orders.length + 1,
customerId: user.id,
customerName: user.name,
beverageName,
status: "placed",
};
orders.push(newOrder);
return newOrder.orderId;
}
// 음료 준비 완료 API - 어드민
function completeOrder(user, orderId) {
if (!isAdmin(user)) {
console.log("권한이 없습니다.");
return;
}
const order = orders.find((order) => order.orderId === orderId);
if (order) {
order.status = "completed"; // 단순히 주문의 상태만 바꾸고 끝!
console.log(
`[고객 메시지] ${order.customerName}님~ 주문하신 ${order.beverageName} 1잔 나왔습니다~`
);
}
}
// 음료 수령 API - 고객
function pickUpOrder(user, orderId) {
if (!isCustomer(user)) {
console.log("권한이 없습니다.");
return;
}
const order = orders.find(
(order) => order.orderId === orderId && order.customerId === user.id
);
if (order && order.status === "completed") {
order.status = "picked-up";
console.log(
`[어드민 메시지] 고객 ID[${order.customerId}]님이 주문 ID[${orderId}]을 수령했습니다.`
);
}
}
// 테스트
function main() {
const admin = {
id: 1,
name: "바리스타",
role: "admin",
};
// 유저 생성
const member1 = {
id: 2,
name: "ctrs",
role: "customer",
};
const member2 = {
id: 3,
name: "testCust",
role: "customer",
};
// 음료 등록
addBeverage(admin, "아메리카노", 4000);
addBeverage(admin, "카페라떼", 4500);
addBeverage(admin, "에스프레소", 3000);
// 음료 삭제
removeBeverage(admin, "에스프레소");
console.log(
`안녕하세요~ ${
member1.name
} 고객님! 카페에 오신 것을 환영합니다. 저희는 ${JSON.stringify(
getBeverages(member1)
)}를 판매하고 있습니다.`
);
// 음료 주문
const orderId1 = placeOrder(member1, "아메리카노");
if (orderId1 > 0) {
setTimeout(() => {
// 음료 제작 완료
completeOrder(admin, orderId1);
// 음료 수령
pickUpOrder(member1, orderId1);
}, 1000);
}
console.log(
`안녕하세요~ ${
member2.name
} 고객님! 카페에 오신 것을 환영합니다. 저희는 ${JSON.stringify(
getBeverages(member2)
)}를 판매하고 있습니다.`
);
// 음료 주문
const orderId2 = placeOrder(member2, "카페라떼");
if (orderId2 > 0) {
setTimeout(() => {
// 음료 제작 완료
completeOrder(admin, orderId2);
// 음료 수령
pickUpOrder(member2, orderId2);
}, 3000);
}
}
// 테스트 코드 실행
main();
6. /dist/index.js 파일 실행
$ npm run start
> 03.-starbucks@1.0.0 start
> tsc && node ./dist/index.js
안녕하세요~ ctrs 고객님! 카페에 오신 것을 환영합니다. 저희는 [{"name":"아메리카노","price":4000},{"name":"카페라떼","price":4500}]를 판매하고 있습니다.
안녕하세요~ testCust 고객님! 카페에 오신 것을 환영합니다. 저희는 [{"name":"아메리카노","price":4000},{"name":"카페라떼","price":4500}]를 판매하고 있습니다.
[고객 메시지] ctrs님~ 주문하신 아메리카노 1잔 나왔습니다~
[어드민 메시지] 고객 ID[2]님이 주문 ID[1]을 수령했습니다.
[고객 메시지] testCust님~ 주문하신 카페라떼 1잔 나왔습니다~
[어드민 메시지] 고객 ID[3]님이 주문 ID[2]을 수령했습니다.
'공부 > TypeScript' 카테고리의 다른 글
객체 지향 프로그래밍 - 상속 (0) | 2023.08.01 |
---|---|
객체 지향 프로그래밍 - 클래스 (0) | 2023.08.01 |
타입스크립트에서 자주 쓰이는 유틸리티 타입 (0) | 2023.07.29 |
타입스크립트에서의 데이터 타입 사용 방법 2 - any, unknown, union, object literal (0) | 2023.07.29 |
타입스크립트에서의 변수, 상수 선언 - let, const, readonly (0) | 2023.07.29 |