TypeScript for JavaScript Developers
TypeScript for JavaScript Developers
TypeScript is a superset of JavaScript that adds static typing and other features to help you build more robust applications. If you're a JavaScript developer looking to level up your skills, TypeScript is a natural next step.
Why TypeScript?
JavaScript is dynamically typed, which means variables can change types during runtime. While this flexibility is powerful, it can lead to unexpected bugs. TypeScript helps catch these issues during development by adding static type checking.
Benefits include:
- Catch errors early: Type checking helps identify bugs before runtime
- Better IDE support: Enhanced autocomplete, navigation, and refactoring
- Self-documenting code: Types serve as documentation for your functions and variables
- Safer refactoring: The compiler helps ensure changes don't break existing code
Getting Started
To start using TypeScript, you'll need to install it:
npm install -g typescript
Create a simple TypeScript file (e.g., hello.ts
):
function greet(name: string): string {
return `Hello, ${name}!`;
}
console.log(greet("TypeScript"));
Compile it to JavaScript:
tsc hello.ts
This generates a JavaScript file that you can run with Node.js.
Basic Types
TypeScript provides several basic types:
// Primitive types
let isDone: boolean = false;
let decimal: number = 6;
let color: string = "blue";
// Arrays
let list: number[] = [1, 2, 3];
let names: Array<string> = ["Alice", "Bob"];
// Tuple
let tuple: [string, number] = ["hello", 10];
// Enum
enum Color {Red, Green, Blue}
let c: Color = Color.Green;
// Any (avoid when possible)
let notSure: any = 4;
// Void (for functions with no return value)
function warnUser(): void {
console.log("Warning!");
}
// Null and Undefined
let u: undefined = undefined;
let n: null = null;
// Never (for functions that never return)
function error(message: string): never {
throw new Error(message);
}
Interfaces
Interfaces define the shape of objects:
interface User {
id: number;
name: string;
email: string;
age?: number; // Optional property
readonly createdAt: Date; // Can't be modified after creation
}
function createUser(user: User): User {
return user;
}
const newUser = createUser({
id: 1,
name: "John Doe",
email: "john@example.com",
createdAt: new Date()
});
Type Aliases
Type aliases create custom types:
type ID = string | number;
type Point = {
x: number;
y: number;
};
function printCoord(pt: Point) {
console.log(`Coordinates: ${pt.x}, ${pt.y}`);
}
Functions
TypeScript enhances function declarations with parameter and return types:
// Function with typed parameters and return type
function add(a: number, b: number): number {
return a + b;
}
// Optional parameters
function buildName(firstName: string, lastName?: string): string {
return lastName ? `${firstName} ${lastName}` : firstName;
}
// Default parameters
function greet(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}!`;
}
// Rest parameters
function sum(...numbers: number[]): number {
return numbers.reduce((total, n) => total + n, 0);
}
// Function types
type MathOperation = (a: number, b: number) => number;
const multiply: MathOperation = (a, b) => a * b;
Classes
TypeScript adds type annotations to classes:
class Person {
private name: string;
protected age: number;
public readonly id: number;
constructor(name: string, age: number, id: number) {
this.name = name;
this.age = age;
this.id = id;
}
greet(): string {
return `Hello, my name is ${this.name}`;
}
}
class Employee extends Person {
constructor(name: string, age: number, id: number,
private department: string) {
super(name, age, id);
}
introduce(): string {
return `${this.greet()} and I work in ${this.department}`;
}
}
Generics
Generics allow you to create reusable components:
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("myString");
// or let TypeScript infer the type
let output2 = identity(42); // Type is number
// Generic interfaces
interface Box<T> {
value: T;
}
let box: Box<string> = { value: "hello" };
TypeScript with React
TypeScript works great with React:
type ButtonProps = {
text: string;
onClick?: () => void;
color?: 'primary' | 'secondary' | 'danger';
};
const Button: React.FC<ButtonProps> = ({
text,
onClick,
color = 'primary'
}) => {
return (
<button
className={`btn btn-${color}`}
onClick={onClick}
>
{text}
</button>
);
};
Conclusion
TypeScript adds a powerful type system to JavaScript that can help you write more robust code with fewer bugs. While there is a learning curve, the benefits of static typing, better tooling, and improved code quality make it worth the investment for many developers and teams.
As you continue your TypeScript journey, you'll discover more advanced features like conditional types, mapped types, and utility types that can make your code even more expressive and type-safe.