Calculator App Using TypeScript
Last Updated :
22 Jan, 2025
Improve
A calculator app is a perfect project for practising TypeScript along with HTML and CSS. This app will have basic functionalities like addition, subtraction, multiplication, and division. It provides a clean and interactive interface for the user while using TypeScript to handle logic safely and efficiently.
What We’re Going to Create
We’ll build a calculator app with the following features:
- Basic arithmetic operations: addition, subtraction, multiplication, and division.
- An interactive display for user inputs and results.
- Responsive styling for a polished user experience.
Project Preview

Calculator App – HTML and CSS Setup
Below is the combined HTML and CSS code that structures and styles the calculator app
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.calculator {
background-color: #fff;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
padding: 20px;
width: 300px;
text-align: center;
}
h1 {
font-size: 24px;
margin-bottom: 20px;
}
#display {
width: 100%;
height: 50px;
font-size: 36px;
text-align: right;
padding: 10px;
border: 1px solid #ccc;
margin-bottom: 20px;
background-color: #f9f9f9;
border-radius: 8px;
}
#buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
button {
padding: 20px;
font-size: 18px;
cursor: pointer;
background-color: #f1f1f1;
border: 1px solid #ddd;
border-radius: 8px;
transition: background-color 0.3s;
}
button:hover {
background-color: #e2e2e2;
}
button:active {
background-color: #ccc;
}
.clear {
background-color: #ff4d4d;
color: white;
}
.clear:hover {
background-color: #ff3333;
}
.equals {
background-color: #4CAF50;
color: white;
grid-column: span 2;
}
.equals:hover {
background-color: #45a049;
}
.operator {
background-color: #f1f1f1;
}
.number {
background-color: #f9f9f9;
}
</style>
</head>
<body>
<div class="calculator">
<h1>TypeScript Calculator</h1>
<input type="text" id="display" disabled />
<div id="buttons">
<button class="number">1</button>
<button class="number">2</button>
<button class="number">3</button>
<button class="operator">+</button>
<button class="number">4</button>
<button class="number">5</button>
<button class="number">6</button>
<button class="operator">-</button>
<button class="number">7</button>
<button class="number">8</button>
<button class="number">9</button>
<button class="operator">*</button>
<button class="number">0</button>
<button class="clear">C</button>
<button class="equals">=</button>
<button class="operator">/</button>
</div>
</div>
</body>
</html>
Explanation of the Code
- HTML Structure
- The display input field shows the current input or result.
- Buttons are grouped into numbers, operators, equals, and clear, laid out in a grid format.
- CSS Styling
- Provides a responsive and polished look with hover effects for buttons.
- Grid layout ensures proper alignment of buttons.
Calculator App – TypeScript Logic
The TypeScript code handles the calculator logic, including user input, operator selection, and computations.
type Operator = '+' | '-' | '*' | '/';
class Calculator {
private currentInput: string = '';
private previousInput: string = '';
private operator: Operator | null = null;
public appendNumber(number: string): void {
if (this.currentInput === '0' && number !== '.') {
this.currentInput = number;
} else if (number === '.' && !this.currentInput.includes('.')) {
this.currentInput += number;
} else {
this.currentInput += number;
}
this.updateDisplay();
}
public chooseOperator(operator: Operator): void {
if (this.currentInput === '') return;
if (this.previousInput !== '') {
this.compute();
}
this.operator = operator;
this.previousInput = this.currentInput;
this.currentInput = '';
}
public compute(): void {
let computation: number;
const prev = parseFloat(this.previousInput);
const current = parseFloat(this.currentInput);
if (isNaN(prev) || isNaN(current)) return;
switch (this.operator) {
case '+':
computation = prev + current;
break;
case '-':
computation = prev - current;
break;
case '*':
computation = prev * current;
break;
case '/':
computation = prev / current;
break;
default:
return;
}
this.currentInput = computation.toString();
this.operator = null;
this.previousInput = '';
this.updateDisplay();
}
public updateDisplay(): void {
const display = document.getElementById('display') as HTMLInputElement;
display.value = this.currentInput;
}
public clear(): void {
this.currentInput = '';
this.previousInput = '';
this.operator = null;
this.updateDisplay();
}
}
const calculator = new Calculator();
document.getElementById('buttons')!.addEventListener('click', (event) => {
const target = event.target as HTMLElement;
if (target.classList.contains('number')) {
calculator.appendNumber(target.innerText);
} else if (target.classList.contains('operator')) {
calculator.chooseOperator(target.innerText as Operator);
} else if (target.classList.contains('equals')) {
calculator.compute();
} else if (target.classList.contains('clear')) {
calculator.clear();
}
});
In this example
- Calculator class: Manages the current and previous inputs, operator, and computes results.
- appendNumber: Appends numbers to the current input, preventing multiple leading zeros or decimal points.
- chooseOperator: Stores the selected operator and moves the current input to the previous input.
- compute: Performs the arithmetic operation based on the selected operator and updates the display.
- updateDisplay: Updates the input field to show the current input.
- clear: Resets all inputs and the operator.
- Event listeners: Listens for button clicks to append numbers, choose operators, compute results, or clear the inputs.
Convert to JavaScript File
Now You need to convert the TypeScript file into JavaScript to render by browser. Use one of the following command-
npx tsc task.ts
tsc task.ts
- The command tsc task.ts compiles the calculator.ts TypeScript file into a task.js JavaScript file.
- It places the output in the same directory as the input file by default.
Complete Code
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.calculator {
background-color: #fff;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
padding: 20px;
width: 300px;
text-align: center;
}
h1 {
font-size: 24px;
margin-bottom: 20px;
}
#display {
width: 100%;
height: 50px;
font-size: 36px;
text-align: right;
padding: 10px;
border: 1px solid #ccc;
margin-bottom: 20px;
background-color: #f9f9f9;
border-radius: 8px;
}
#buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
button {
padding: 20px;
font-size: 18px;
cursor: pointer;
background-color: #f1f1f1;
border: 1px solid #ddd;
border-radius: 8px;
transition: background-color 0.3s;
}
button:hover {
background-color: #e2e2e2;
}
button:active {
background-color: #ccc;
}
.clear {
background-color: #ff4d4d;
color: white;
}
.clear:hover {
background-color: #ff3333;
}
.equals {
background-color: #4CAF50;
color: white;
grid-column: span 2;
}
.equals:hover {
background-color: #45a049;
}
.operator {
background-color: #f1f1f1;
}
.number {
background-color: #f9f9f9;
}
</style>
</head>
<body>
<div class="calculator">
<h1>TypeScript Calculator</h1>
<input type="text" id="display" disabled />
<div id="buttons">
<button class="number">1</button>
<button class="number">2</button>
<button class="number">3</button>
<button class="operator">+</button>
<button class="number">4</button>
<button class="number">5</button>
<button class="number">6</button>
<button class="operator">-</button>
<button class="number">7</button>
<button class="number">8</button>
<button class="number">9</button>
<button class="operator">*</button>
<button class="number">0</button>
<button class="clear">C</button>
<button class="equals">=</button>
<button class="operator">/</button>
</div>
</div>
<script>
var Calculator = /** @class */ (function () {
function Calculator() {
this.currentInput = '';
this.previousInput = '';
this.operator = null;
}
Calculator.prototype.appendNumber = function (number) {
if (this.currentInput === '0' && number !== '.') {
this.currentInput = number;
}
else {
this.currentInput += number;
}
this.updateDisplay();
};
Calculator.prototype.chooseOperator = function (operator) {
if (this.currentInput === '')
return;
if (this.previousInput !== '') {
this.compute();
}
this.operator = operator;
this.previousInput = this.currentInput;
this.currentInput = '';
};
Calculator.prototype.compute = function () {
var computation;
var prev = parseFloat(this.previousInput);
var current = parseFloat(this.currentInput);
if (isNaN(prev) || isNaN(current))
return;
switch (this.operator) {
case '+':
computation = prev + current;
break;
case '-':
computation = prev - current;
break;
case '*':
computation = prev * current;
break;
case '/':
computation = prev / current;
break;
default:
return;
}
this.currentInput = computation.toString();
this.operator = null;
this.previousInput = '';
this.updateDisplay();
};
Calculator.prototype.updateDisplay = function () {
var display = document.getElementById('display');
display.value = this.currentInput;
};
Calculator.prototype.clear = function () {
this.currentInput = '';
this.previousInput = '';
this.operator = null;
this.updateDisplay();
};
return Calculator;
}());
var calculator = new Calculator();
document.getElementById('buttons').addEventListener('click', function (event) {
var target = event.target;
if (target.classList.contains('number')) {
calculator.appendNumber(target.innerText);
}
else if (target.classList.contains('operator')) {
calculator.chooseOperator(target.innerText);
}
else if (target.classList.contains('equals')) {
calculator.compute();
}
else if (target.classList.contains('clear')) {
calculator.clear();
}
});
</script>
</body>
</html>