Learn2Code
learn2code
← Back to Blog
TypeScript11 min read

TypeScript for JavaScript Developers: A Practical Getting Started Guide

Already know JavaScript? Learn TypeScript in the most efficient way. This guide covers types, interfaces, generics, and the key differences that matter for real-world development.

Learn2Code Team

January 25, 2026

Why TypeScript Exists

TypeScript is JavaScript with static types. That single addition solves the most common source of bugs in JavaScript codebases: type errors.

In JavaScript, you discover type bugs at runtime -- when your app crashes in production because someone passed a string where a number was expected. In TypeScript, you discover them at compile time -- before the code ever runs. Your editor underlines the problem while you type.

In 2026, TypeScript is no longer optional for professional web development. Most major companies require it. React, Angular, Next.js, and Deno all use TypeScript extensively. The question is not whether to learn it, but when.

If you already know JavaScript, the answer is now.

What TypeScript Adds to JavaScript

TypeScript is a strict superset of JavaScript. Every valid JavaScript program is also valid TypeScript. TypeScript adds:

  1. Static type annotations -- declare what types variables, parameters, and return values should be
  2. Interfaces and type aliases -- define the shape of objects
  3. Generics -- write reusable code that works with multiple types
  4. Enums -- define named constants
  5. Type inference -- TypeScript often figures out types without explicit annotations

The key insight: TypeScript does not add new runtime behavior. It only adds compile-time checks. All TypeScript code compiles down to plain JavaScript.

Your First TypeScript Code

Basic Type Annotations

code.ts
1// JavaScript
2let name = "Alice";
3let age = 30;
4let isActive = true;
5 
6// TypeScript -- same thing with explicit types
7let name: string = "Alice";
8let age: number = 30;
9let isActive: boolean = true;

In practice, TypeScript infers these basic types automatically. You write explicit annotations when the type is not obvious from the value.

Function Types

This is where TypeScript shines. JavaScript functions accept anything and return anything. TypeScript makes the contract explicit.

code.ts
1// JavaScript -- what does this return? What types does it accept?
2function calculateTax(price, taxRate) {
3 return price * taxRate;
4}
5 
6// TypeScript -- the contract is clear
7function calculateTax(price: number, taxRate: number): number {
8 return price * taxRate;
9}
10 
11// Now this is a compile-time error, not a runtime surprise
12calculateTax("100", 0.2); // Error: Argument of type 'string' is not assignable to parameter of type 'number'

Arrays

code.ts
1// Array of strings
2let fruits: string[] = ["apple", "banana", "orange"];
3 
4// Array of numbers
5let scores: number[] = [95, 87, 92, 78];
6 
7// TypeScript catches this
8fruits.push(42); // Error: Argument of type 'number' is not assignable to parameter of type 'string'

Objects with Interfaces

Interfaces define the shape of objects. They are one of TypeScript's most useful features.

code.ts
1interface User {
2 id: number;
3 name: string;
4 email: string;
5 isAdmin: boolean;
6}
7 
8function greetUser(user: User): string {
9 return `Hello, ${user.name}!`;
10}
11 
12// This works
13greetUser({ id: 1, name: "Alice", email: "alice@example.com", isAdmin: false });
14 
15// This fails -- missing required properties
16greetUser({ id: 1, name: "Alice" }); // Error: missing email and isAdmin

Optional Properties

Not every property is always present. Use ? to mark optional properties.

code.ts
1interface UserProfile {
2 name: string;
3 email: string;
4 bio?: string; // optional
5 website?: string; // optional
6}
7 
8// Both are valid
9const user1: UserProfile = { name: "Alice", email: "a@b.com" };
10const user2: UserProfile = { name: "Bob", email: "b@b.com", bio: "Developer" };

Union Types: This OR That

Sometimes a value can be more than one type. Union types handle this.

code.ts
1// Can be a string or a number
2let id: string | number;
3id = "abc-123"; // valid
4id = 42; // valid
5id = true; // Error: Type 'boolean' is not assignable
6 
7// Useful for function parameters
8function formatId(id: string | number): string {
9 if (typeof id === "string") {
10 return id.toUpperCase();
11 }
12 return `#${id}`;
13}

Type Aliases: Name Your Types

Type aliases give names to complex types, making your code more readable.

code.ts
1type Status = "active" | "inactive" | "suspended";
2type UserId = string | number;
3 
4interface User {
5 id: UserId;
6 name: string;
7 status: Status;
8}
9 
10// TypeScript enforces the exact values
11const user: User = {
12 id: 1,
13 name: "Alice",
14 status: "active" // only "active", "inactive", or "suspended" allowed
15};

Generics: Write Reusable Typed Code

Generics let you write functions and types that work with multiple types while preserving type safety.

code.ts
1// Without generics -- works but loses type information
2function getFirst(items: any[]): any {
3 return items[0];
4}
5 
6// With generics -- preserves type information
7function getFirst<T>(items: T[]): T {
8 return items[0];
9}
10 
11const firstNumber = getFirst([1, 2, 3]); // type: number
12const firstString = getFirst(["a", "b", "c"]); // type: string

A common real-world use of generics is API response wrappers:

code.ts
1interface ApiResponse<T> {
2 data: T;
3 status: number;
4 message: string;
5}
6 
7interface User {
8 id: number;
9 name: string;
10}
11 
12// The response is typed to contain User data
13const response: ApiResponse<User> = {
14 data: { id: 1, name: "Alice" },
15 status: 200,
16 message: "Success"
17};

Common Utility Types

TypeScript includes built-in utility types that transform existing types.

code.ts
1interface User {
2 id: number;
3 name: string;
4 email: string;
5 isAdmin: boolean;
6}
7 
8// Make all properties optional
9type PartialUser = Partial<User>;
10 
11// Make all properties required
12type RequiredUser = Required<User>;
13 
14// Select specific properties
15type UserBasic = Pick<User, "id" | "name">;
16 
17// Exclude specific properties
18type UserWithoutAdmin = Omit<User, "isAdmin">;
19 
20// Make all properties read-only
21type ReadonlyUser = Readonly<User>;

These are particularly useful for update functions where you only want to change some fields:

code.ts
1function updateUser(id: number, updates: Partial<User>): User {
2 // Only pass the fields you want to change
3 // ...
4}
5 
6updateUser(1, { name: "New Name" }); // valid -- only updating name

Migrating from JavaScript to TypeScript

You do not need to rewrite your entire codebase. TypeScript supports gradual adoption.

Step 1: Rename Files

Change .js files to .ts (or .jsx to .tsx for React). TypeScript will immediately start checking your code and reporting issues.

Step 2: Fix the Easy Errors

Most initial errors are straightforward:

  • Add type annotations to function parameters
  • Define interfaces for your data structures
  • Fix actual bugs that TypeScript caught (these are wins)

Step 3: Use any Sparingly as a Temporary Fix

If a type is too complex to define immediately, you can use any as a temporary escape hatch:

code.ts
1// Temporary -- come back and type this properly
2let complexData: any = fetchData();

But treat any as technical debt. Every any is a place where TypeScript cannot help you.

Step 4: Enable Strict Mode Gradually

TypeScript has a strict flag in tsconfig.json that enables all strict type checks. Start with it off, then turn it on once you have typed most of your code.

TypeScript with React

TypeScript and React work together naturally. Here are the most common patterns:

Typing Props

code.ts
1interface ButtonProps {
2 label: string;
3 onClick: () => void;
4 variant?: "primary" | "secondary";
5 disabled?: boolean;
6}
7 
8function Button({ label, onClick, variant = "primary", disabled = false }: ButtonProps) {
9 return (
10 <button onClick={onClick} disabled={disabled} className={variant}>
11 {label}
12 </button>
13 );
14}

Typing State

code.ts
1const [count, setCount] = useState<number>(0);
2const [user, setUser] = useState<User | null>(null);
3const [items, setItems] = useState<string[]>([]);

Typing Events

code.ts
1function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
2 console.log(event.target.value);
3}
4 
5function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
6 event.preventDefault();
7}

Common Mistakes When Starting TypeScript

Mistake 1: Over-typing Everything

TypeScript has excellent type inference. You do not need to annotate everything.

code.ts
1// Unnecessary -- TypeScript already knows this is a string
2const name: string = "Alice";
3 
4// Better -- let TypeScript infer it
5const name = "Alice";

Annotate function parameters and return types. Let TypeScript infer the rest.

Mistake 2: Using any Everywhere

If every type is any, you are writing JavaScript with extra syntax. Use unknown instead of any when you genuinely do not know the type -- it forces you to check the type before using the value.

Mistake 3: Ignoring Compiler Errors

TypeScript errors exist to help you. Suppressing them with @ts-ignore or as any defeats the purpose. Fix the underlying type issue instead.

Mistake 4: Not Using Strict Mode

Strict mode catches the most common bugs. Enable it as soon as possible in your tsconfig.json:

code.js
1{
2 "compilerOptions": {
3 "strict": true
4 }
5}

Start Writing TypeScript Today

If you know JavaScript, you already know most of TypeScript. The type system is an addition, not a replacement. Start by:

  1. Converting one small file from .js to .ts
  2. Adding type annotations to function parameters
  3. Defining interfaces for your main data structures
  4. Fixing the errors TypeScript finds (many will be real bugs)

Within a week, you will wonder how you ever wrote JavaScript without types.

Practice your TypeScript syntax with our interactive TypeScript exercises and keep our TypeScript cheatsheet bookmarked for quick reference.

Related Reading

#typescript#javascript#web-development#types#frontend

Ready to practice what you learned?

Apply these concepts with our interactive coding exercises.

Start Practicing