Introduction to TypeScript: Why It Exists and How It Improves JavaScript

This is the first post in a series where I will study TypeScript step by step.
The goal is simple: learn TypeScript by writing about it.
I have worked with JavaScript for many years, especially in frontend development with technologies such as React, HTML, CSS, and the modern web ecosystem. However, TypeScript has become increasingly important in both frontend and backend projects, and understanding it well is no longer just a nice-to-have skill.
In this first article, I want to start with the basics:
- What TypeScript is
- Why TypeScript exists
- TypeScript vs JavaScript
- Static typing vs dynamic typing
- Type checking during development
- Compilation from TypeScript to JavaScript
- TypeScript in frontend and backend projects
What Is TypeScript?
TypeScript is a programming language built on top of JavaScript.
A common way to describe it is:
TypeScript is JavaScript with types.
That means TypeScript does not replace JavaScript. Instead, it extends JavaScript by adding features such as static typing, better tooling support, and compile-time checks.
A simple JavaScript example looks like this:
let name = "Jaison";
let age = 35;
let isActive = true;
In TypeScript, we can explicitly define the types of these variables:
let name: string = "Jaison";
let age: number = 35;
let isActive: boolean = true;
In this example:
namemust be a stringagemust be a numberisActivemust be a boolean
This helps TypeScript understand how the code is expected to behave.
It is important to understand that TypeScript is a superset of JavaScript. In practice, this means that most valid JavaScript code is also valid TypeScript code.
Why TypeScript Exists
JavaScript is a very flexible language.
This flexibility is one of the reasons why JavaScript became so popular. It can run in the browser, on the backend with Node.js, in mobile apps, desktop apps, serverless functions, and many other environments.
However, flexibility can also create problems.
For example:
function sum(a, b) {
return a + b;
}
console.log(sum(10, 20)); // 30
console.log(sum(10, "20")); // "1020"
In the first call, JavaScript adds two numbers.
In the second call, JavaScript receives a number and a string. Instead of returning 30, it returns "1020" because JavaScript converts the number to a string and performs string concatenation.
This behavior may be valid JavaScript, but it can also cause bugs.
With TypeScript, we can make the expected types explicit:
function sum(a: number, b: number): number {
return a + b;
}
sum(10, 20); // OK
sum(10, "20"); // Error during development
In this case, TypeScript warns us before the code runs.
This is one of the main reasons TypeScript exists: to help developers catch problems earlier, especially in larger applications.
TypeScript vs JavaScript
TypeScript and JavaScript are closely related, but they are not exactly the same thing.
JavaScript is the language that runs directly in browsers and JavaScript runtimes such as Node.js.
TypeScript is a development-time language that is compiled to JavaScript before execution.
| Aspect | JavaScript | TypeScript |
|---|---|---|
| Typing | Dynamic | Static and optional |
| Execution | Runs directly in browsers and runtimes | Must be compiled to JavaScript |
| Error detection | Mostly at runtime | During development and compilation |
| Learning curve | Easier to start | Requires learning types and configuration |
| Tooling | Good | Usually better because of type information |
| Large projects | Possible, but requires discipline | Easier to maintain and refactor |
TypeScript should not be seen as a competitor to JavaScript.
It is better to think of TypeScript as a layer on top of JavaScript that improves the development experience.
Static Typing vs Dynamic Typing
One of the most important concepts in TypeScript is static typing.
JavaScript is dynamically typed. This means that variable types are checked during execution.
For example:
let value = "hello";
value = 123;
value = true;
JavaScript allows this.
The same variable starts as a string, then becomes a number, and later becomes a boolean.
This can be useful in small scripts, but in larger systems it can make the code harder to understand and maintain.
With TypeScript, we can define the expected type:
let value: string = "hello";
value = 123; // Error
Now TypeScript knows that value should always be a string.
Static typing does not mean the application will have no bugs. However, it helps prevent many common mistakes before the application is executed.
Type Checking During Development
One of the biggest benefits of TypeScript is the feedback it provides during development.
When using TypeScript with an editor like Visual Studio Code, the editor can understand your code better.
This improves the development experience in several ways:
- Better autocomplete
- Early error detection
- Safer refactoring
- Better documentation inside the code
- Easier navigation between files, types, and functions
Consider this example:
type User = {
name: string;
email: string;
};
function sendEmail(user: User) {
console.log(`Sending email to ${user.email}`);
}
sendEmail({
name: "Jaison",
});
The function expects a User object with both name and email.
However, the object passed to sendEmail only has name.
TypeScript will show an error because the email property is missing.
This kind of feedback is very useful because it helps us fix problems before running the application.
Compilation from TypeScript to JavaScript
Browsers do not usually execute TypeScript directly.
Node.js projects also commonly compile TypeScript before running the final application.
The basic flow is:
TypeScript code (.ts)
↓
TypeScript compiler or build tool
↓
JavaScript code (.js)
↓
Browser, Node.js, Deno, Bun, or another runtime
For example, this TypeScript code:
const message: string = "Hello TypeScript";
console.log(message);
Can be compiled to JavaScript similar to this:
const message = "Hello TypeScript";
console.log(message);
Notice that the type annotation : string disappears in the generated JavaScript.
This happens because types are mainly used during development and compilation. They help developers and tools, but they are not usually present in the final JavaScript code.
TypeScript in Frontend Projects
TypeScript is widely used in frontend development.
It works very well with modern frameworks and libraries such as:
- React
- Vue
- Angular
- Next.js
- Nuxt
- Vite
In React, for example, TypeScript can help define component props.
type ButtonProps = {
label: string;
onClick: () => void;
};
function Button({ label, onClick }: ButtonProps) {
return <button onClick={onClick}>{label}</button>;
}
In this example, the Button component expects two props:
label, which must be a stringonClick, which must be a function that returns nothing
If another developer tries to use this component incorrectly, TypeScript can warn them.
For example:
<Button label={123} onClick={() => console.log("Clicked")} />
This would cause a TypeScript error because label should be a string, not a number.
In frontend projects, TypeScript helps make components, hooks, services, API responses, and application state more predictable.
TypeScript in Backend Projects
TypeScript is also very common in backend development, especially with Node.js.
It can be used with frameworks such as:
- Express
- Fastify
- NestJS
- Hono
- AdonisJS
In backend applications, TypeScript helps define the shape of inputs, outputs, services, entities, repositories, and API contracts.
For example:
type CreateUserInput = {
name: string;
email: string;
};
type User = {
id: string;
name: string;
email: string;
};
function createUser(input: CreateUserInput): User {
return {
id: crypto.randomUUID(),
name: input.name,
email: input.email,
};
}
Here, the function createUser receives a specific input and returns a specific user object.
This makes the code easier to understand and safer to change.
In backend projects, TypeScript can be especially useful when working with:
- REST APIs
- GraphQL APIs
- Database models
- Validation schemas
- Business rules
- Service layers
- Domain models
The more the backend grows, the more valuable type safety becomes.
TypeScript Does Not Replace Learning JavaScript
One important point is that TypeScript does not remove the need to learn JavaScript.
TypeScript is built on top of JavaScript.
That means we still need to understand concepts such as:
- Variables
- Functions
- Objects
- Arrays
- Promises
- Async/await
- Closures
- Modules
- The JavaScript runtime
- The DOM, in frontend projects
Learning TypeScript without understanding JavaScript can create confusion.
So, in my view, the best path is:
Learn JavaScript fundamentals
↓
Understand common JavaScript problems
↓
Learn TypeScript to improve safety and maintainability
TypeScript makes more sense when we understand the problems it is trying to solve.
When TypeScript Helps the Most
TypeScript is useful in many situations, but it becomes especially valuable when:
- The project has many developers
- The codebase is growing
- The business rules are complex
- The application has many API integrations
- Refactoring is frequent
- Components and functions are reused in many places
- Bugs caused by wrong data shapes are common
In small scripts or quick prototypes, JavaScript may be enough.
But in professional applications, TypeScript can bring more confidence and structure.
Conclusion
TypeScript is not a completely different world from JavaScript.
It is JavaScript with an additional layer of type safety, tooling, and development-time validation.
In this first post, I learned that TypeScript exists to help developers catch errors earlier, improve code readability, and make applications easier to maintain as they grow.
The main idea I want to keep is:
TypeScript does not replace JavaScript. It helps us write JavaScript with more confidence.
In the next post, I want to create a simple TypeScript project from scratch, install the necessary tools, understand the tsconfig.json file, and run my first TypeScript code.
Next Post
Setting Up the First TypeScript Project: Installation, tsconfig, and First Code
