타입스크립트 간단한 프로젝트
1. 타입스크립트로 계산기 만들기
프로젝트는 웹 환경에서 진행합니다. React, Vue등 다양한 라이브러리나 프레임웤을 이용할 수 있겠지만, 모든 분들이 하나의 스택을 배우고 있지 않을 수 있기 때문에 가장 기본적인 방법을 사용하겠습니다.
1.1 프로젝트 생성
먼저 프로젝트를 생성합니다. 프로젝트 생성은 index.html
, calculator.ts
파일을 생성하고 다음과 같이 작성합니다.
<!DOCTYPE html>
<html>
<head>
<title>TypeScript Calculator</title>
<style>
.calculator {
width: 300px;
margin: 50px auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 5px;
}
.display {
width: 100%;
height: 40px;
margin-bottom: 10px;
font-size: 20px;
text-align: right;
}
.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 5px;
}
button {
padding: 10px;
font-size: 18px;
border: 1px solid #ccc;
border-radius: 5px;
background: #f0f0f0;
cursor: pointer;
}
button:hover {
background: #e0e0e0;
}
</style>
</head>
<body>
<div class="calculator">
<input type="text" class="display" readonly>
<div class="buttons">
<button>7</button>
<button>8</button>
<button>9</button>
<button>+</button>
<button>4</button>
<button>5</button>
<button>6</button>
<button>-</button>
<button>1</button>
<button>2</button>
<button>3</button>
<button>*</button>
<button>C</button>
<button>0</button>
<button>=</button>
<button>/</button>
</div>
</div>
<!-- TypeScript CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/typescript/5.3.3/typescript.min.js"></script>
<!-- TypeScript 파일 로드 -->
<script>
// TypeScript 파일을 가져와서 컴파일하고 실행하는 함수
async function loadAndCompileTS() {
try {
// calculator.ts 파일 가져오기
const response = await fetch('calculator.ts');
const tsCode = await response.text();
// TypeScript 코드 컴파일
const jsCode = ts.transpileModule(tsCode, {
compilerOptions: {
target: ts.ScriptTarget.ES5,
module: ts.ModuleKind.None
}
}).outputText;
// 컴파일된 JavaScript 실행
const script = document.createElement('script');
script.textContent = jsCode;
document.body.appendChild(script);
} catch (error) {
console.error('TypeScript 파일 로드 실패:', error);
}
}
// DOM이 로드된 후 TypeScript 파일 로드
window.addEventListener('DOMContentLoaded', loadAndCompileTS);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>TypeScript Calculator</title>
<style>
.calculator {
width: 300px;
margin: 50px auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 5px;
}
.display {
width: 100%;
height: 40px;
margin-bottom: 10px;
font-size: 20px;
text-align: right;
}
.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 5px;
}
button {
padding: 10px;
font-size: 18px;
border: 1px solid #ccc;
border-radius: 5px;
background: #f0f0f0;
cursor: pointer;
}
button:hover {
background: #e0e0e0;
}
</style>
</head>
<body>
<div class="calculator">
<input type="text" class="display" readonly>
<div class="buttons">
<button>7</button>
<button>8</button>
<button>9</button>
<button>+</button>
<button>4</button>
<button>5</button>
<button>6</button>
<button>-</button>
<button>1</button>
<button>2</button>
<button>3</button>
<button>*</button>
<button>C</button>
<button>0</button>
<button>=</button>
<button>/</button>
</div>
</div>
<!-- TypeScript CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/typescript/5.3.3/typescript.min.js"></script>
<!-- TypeScript 파일 로드 -->
<script>
// TypeScript 파일을 가져와서 컴파일하고 실행하는 함수
async function loadAndCompileTS() {
try {
// calculator.ts 파일 가져오기
const response = await fetch('calculator.ts');
const tsCode = await response.text();
// TypeScript 코드 컴파일
const jsCode = ts.transpileModule(tsCode, {
compilerOptions: {
target: ts.ScriptTarget.ES5,
module: ts.ModuleKind.None
}
}).outputText;
// 컴파일된 JavaScript 실행
const script = document.createElement('script');
script.textContent = jsCode;
document.body.appendChild(script);
} catch (error) {
console.error('TypeScript 파일 로드 실패:', error);
}
}
// DOM이 로드된 후 TypeScript 파일 로드
window.addEventListener('DOMContentLoaded', loadAndCompileTS);
</script>
</body>
</html>
다음으로 calculator.ts
파일을 생성하고 다음과 같이 작성합니다.
// calculator.ts
// 계산기 상태를 관리할 인터페이스
interface CalculatorState {
}
// 계산기 클래스
class Calculator {
}
// 계산기 인스턴스 생성
new Calculator();
// calculator.ts
// 계산기 상태를 관리할 인터페이스
interface CalculatorState {
}
// 계산기 클래스
class Calculator {
}
// 계산기 인스턴스 생성
new Calculator();
위 코드를 작성하고 브라우저에서 index.html
파일을 열어 계산기가 작성될 수 있도록 해주세요. 코드의 기본 형태를 변경하더라도 상관없습니다. 예를 들어, class
를 사용하지 않고 function
만 사용해서 구현해도 됩니다. 다만, 계산기의 기능은 최소한 덧셈, 뺄셈, 곱셈, 나눗셈이 가능하도록 만들어주세요. 구현을 하기 전까지는 아래의 힌트를 보지 않는 것을 권장합니다.
1.2 프로젝트 구현과 실행
fetch를 사용하였기 때문에 서버가 필요합니다. VSCode에서는 Liveserver 확장 프로그램을 설치하여 구동해주세요.
// calculator.ts
// 계산기에 필요한 변수들을 선언합니다
let displayValue: string = '0';
let firstNumber: number | null = null;
let operator: string | null = null;
let isWaitingForSecondNumber: boolean = false;
// HTML 요소를 가져옵니다
const display = document.querySelector('.display') as HTMLInputElement;
const buttons = document.querySelector('.buttons') as HTMLDivElement;
// 화면에 숫자를 표시하는 함수
function updateDisplay(): void {
display.value = displayValue;
}
// 숫자 버튼을 눌렀을 때 실행되는 함수
function inputNumber(number: string): void {
if (isWaitingForSecondNumber) {
displayValue = number;
isWaitingForSecondNumber = false;
} else {
// 현재 화면에 0만 있다면 새로운 숫자로 바꾸고, 아니면 뒤에 붙입니다
displayValue = displayValue === '0' ? number : displayValue + number;
}
updateDisplay();
}
// 연산자 버튼을 눌렀을 때 실행되는 함수
function inputOperator(op: string): void {
const currentNumber = parseFloat(displayValue);
// 첫 번째 숫자가 없다면 현재 숫자를 저장합니다
if (firstNumber === null) {
firstNumber = currentNumber;
} else if (operator) {
// 이미 첫 번째 숫자와 연산자가 있다면 계산을 수행합니다
const result = calculate();
displayValue = String(result);
firstNumber = result;
}
isWaitingForSecondNumber = true;
operator = op;
updateDisplay();
}
// 실제 계산을 수행하는 함수
function calculate(): number {
const secondNumber = parseFloat(displayValue);
if (operator === '+') return firstNumber! + secondNumber;
if (operator === '-') return firstNumber! - secondNumber;
if (operator === '*') return firstNumber! * secondNumber;
if (operator === '/') return firstNumber! / secondNumber;
return secondNumber;
}
// = 버튼을 눌렀을 때 실행되는 함수
function calculateResult(): void {
// 필요한 값들이 모두 있는지 확인합니다
if (firstNumber === null || operator === null) return;
const result = calculate();
displayValue = String(result);
// 계산이 끝났으므로 모든 값을 초기화합니다
firstNumber = null;
operator = null;
isWaitingForSecondNumber = false;
updateDisplay();
}
// C 버튼을 눌렀을 때 실행되는 함수
function clearCalculator(): void {
displayValue = '0';
firstNumber = null;
operator = null;
isWaitingForSecondNumber = false;
updateDisplay();
}
// 버튼 클릭 이벤트를 처리하는 함수
function handleButtonClick(event: Event): void {
const target = event.target as HTMLButtonElement;
if (!target.matches('button')) return;
const value = target.textContent!;
// 눌린 버튼의 종류에 따라 다른 함수를 실행합니다
if ('0123456789'.includes(value)) {
inputNumber(value);
} else if ('+-*/'.includes(value)) {
inputOperator(value);
} else if (value === '=') {
calculateResult();
} else if (value === 'C') {
clearCalculator();
}
}
// 버튼 클릭 이벤트 리스너를 등록합니다
buttons.addEventListener('click', handleButtonClick);
// 초기 화면을 표시합니다
updateDisplay();
// calculator.ts
// 계산기에 필요한 변수들을 선언합니다
let displayValue: string = '0';
let firstNumber: number | null = null;
let operator: string | null = null;
let isWaitingForSecondNumber: boolean = false;
// HTML 요소를 가져옵니다
const display = document.querySelector('.display') as HTMLInputElement;
const buttons = document.querySelector('.buttons') as HTMLDivElement;
// 화면에 숫자를 표시하는 함수
function updateDisplay(): void {
display.value = displayValue;
}
// 숫자 버튼을 눌렀을 때 실행되는 함수
function inputNumber(number: string): void {
if (isWaitingForSecondNumber) {
displayValue = number;
isWaitingForSecondNumber = false;
} else {
// 현재 화면에 0만 있다면 새로운 숫자로 바꾸고, 아니면 뒤에 붙입니다
displayValue = displayValue === '0' ? number : displayValue + number;
}
updateDisplay();
}
// 연산자 버튼을 눌렀을 때 실행되는 함수
function inputOperator(op: string): void {
const currentNumber = parseFloat(displayValue);
// 첫 번째 숫자가 없다면 현재 숫자를 저장합니다
if (firstNumber === null) {
firstNumber = currentNumber;
} else if (operator) {
// 이미 첫 번째 숫자와 연산자가 있다면 계산을 수행합니다
const result = calculate();
displayValue = String(result);
firstNumber = result;
}
isWaitingForSecondNumber = true;
operator = op;
updateDisplay();
}
// 실제 계산을 수행하는 함수
function calculate(): number {
const secondNumber = parseFloat(displayValue);
if (operator === '+') return firstNumber! + secondNumber;
if (operator === '-') return firstNumber! - secondNumber;
if (operator === '*') return firstNumber! * secondNumber;
if (operator === '/') return firstNumber! / secondNumber;
return secondNumber;
}
// = 버튼을 눌렀을 때 실행되는 함수
function calculateResult(): void {
// 필요한 값들이 모두 있는지 확인합니다
if (firstNumber === null || operator === null) return;
const result = calculate();
displayValue = String(result);
// 계산이 끝났으므로 모든 값을 초기화합니다
firstNumber = null;
operator = null;
isWaitingForSecondNumber = false;
updateDisplay();
}
// C 버튼을 눌렀을 때 실행되는 함수
function clearCalculator(): void {
displayValue = '0';
firstNumber = null;
operator = null;
isWaitingForSecondNumber = false;
updateDisplay();
}
// 버튼 클릭 이벤트를 처리하는 함수
function handleButtonClick(event: Event): void {
const target = event.target as HTMLButtonElement;
if (!target.matches('button')) return;
const value = target.textContent!;
// 눌린 버튼의 종류에 따라 다른 함수를 실행합니다
if ('0123456789'.includes(value)) {
inputNumber(value);
} else if ('+-*/'.includes(value)) {
inputOperator(value);
} else if (value === '=') {
calculateResult();
} else if (value === 'C') {
clearCalculator();
}
}
// 버튼 클릭 이벤트 리스너를 등록합니다
buttons.addEventListener('click', handleButtonClick);
// 초기 화면을 표시합니다
updateDisplay();