skip to content
Astro Cactus

Introduction to TypeScript

/ 5 min read

What is TypeScript?

TypeScript is a strongly typed programming language that builds on JavaScript. It’s developed and maintained by Microsoft, and it adds optional static typing, classes, and interfaces to JavaScript. Think of it as JavaScript with superpowers - it provides all of JavaScript’s features plus an additional layer of type safety and development tools.

Key Benefits

  1. Static Typing

    • Catch errors at compile time instead of runtime
    • Better IDE support with intelligent code completion
    • Easier refactoring and maintenance
    • Self-documenting code through type definitions
  2. Enhanced Object-Oriented Features

    • Full support for classes and modules
    • Interface definitions
    • Generics
    • Abstract classes
  3. Modern JavaScript Features

    • Access to the latest ECMAScript features
    • Backwards compatibility with existing JavaScript
    • Ability to compile down to older versions of JavaScript
  4. Better Development Experience

    • Rich IDE support with IntelliSense
    • Improved code navigation
    • Better refactoring tools
    • Clear error messages

Setting Up TypeScript

1. Installation

There are two main ways to install TypeScript:

Terminal window
# Global installation
npm install -g typescript
# Project-specific installation
npm install --save-dev typescript

The global installation is useful for quick experiments and learning, while the project-specific installation is recommended for actual development projects to ensure version consistency across team members.

2. Configuration

TypeScript uses a configuration file called tsconfig.json. Here’s a basic setup with explanations:

{
"compilerOptions": {
// Target ECMAScript version
"target": "ES2020",
// Module system to use
"module": "commonjs",
// Strict type checking options
"strict": true,
// Enable source maps for debugging
"sourceMap": true,
// Output directory for compiled files
"outDir": "./dist",
// Root directory of source files
"rootDir": "./src",
// Additional features
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}

Each option in the configuration serves a specific purpose:

  • target: Specifies which ECMAScript version to compile to
  • module: Determines the module system (CommonJS, ES6, etc.)
  • strict: Enables all strict type checking options
  • sourceMap: Generates source maps for debugging
  • outDir: Specifies where compiled files should go
  • rootDir: Specifies where source files are located

3. Development Environment Setup

For the best TypeScript development experience, you’ll want:

  1. Code Editor/IDE

    • Visual Studio Code (recommended)
    • WebStorm
    • Atom with TypeScript plugins
  2. Essential Extensions

    • TypeScript language service
    • ESLint for TypeScript
    • Prettier for code formatting
  3. Debugging Tools

    • Chrome DevTools with source maps
    • VS Code debugger

Basic Types

TypeScript includes several basic types that form the foundation of its type system. Understanding these is crucial for effective TypeScript development.

1. Primitive Types

// Number
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
// String
let color: string = "blue";
let fullName: string = `Bob Bobbington`;
let sentence: string = `Hello, my name is ${fullName}`;
// Boolean
let isDone: boolean = false;
// Understanding type inference
let inferredNumber = 42; // TypeScript infers number type
let inferredString = "hello"; // TypeScript infers string type

The primitive types in TypeScript directly correspond to the types you’d find in JavaScript, but with added type safety.

2. Arrays and Tuples

// Array
let list: number[] = [1, 2, 3];
let genericList: Array<number> = [1, 2, 3];
// Tuple
let tuple: [string, number] = ["hello", 10];

Arrays in TypeScript can be defined in two ways:

  • Using the type[] syntax
  • Using the generic Array<type> syntax

Tuples are special arrays with a fixed number of elements where each element may have a different type.

3. Special Types

// Any - turn off type checking
let notSure: any = 4;
notSure = "maybe a string";
notSure = false;
// Void - absence of any type
function warnUser(): void {
console.log("Warning message");
}
// Null and Undefined
let u: undefined = undefined;
let n: null = null;
// Never - never occurs
function error(message: string): never {
throw new Error(message);
}

Special types serve specific purposes:

  • any: Opts out of type checking
  • void: Typically used as a return type for functions that don’t return a value
  • null and undefined: Represent absence of value
  • never: Represents values that never occur

Type Annotations and Inference

1. Type Annotations

// Basic annotations
let name: string = "John";
let age: number = 30;
let isStudent: boolean = true;
// Function annotations
function greet(name: string): string {
return `Hello, ${name}!`;
}
// Object annotations
let person: {
name: string;
age: number;
} = {
name: "John",
age: 30
};

Type annotations are explicit ways to tell TypeScript what type a variable, parameter, or return value should be.

2. Type Inference

// TypeScript infers types
let message = "Hello"; // inferred as string
let count = 42; // inferred as number
let isActive = true; // inferred as boolean
// Array inference
let numbers = [1, 2, 3]; // inferred as number[]
let mixed = [1, "hello", true]; // inferred as (string | number | boolean)[]
// Return type inference
function add(x: number, y: number) {
return x + y; // return type inferred as number
}

TypeScript’s type inference is powerful and can often determine the appropriate type without explicit annotations. This leads to cleaner code while maintaining type safety.

Best Practices

  1. Use Type Inference When Possible

    • Let TypeScript infer types when they’re obvious
    • Add explicit types when inference isn’t clear
    • Always type function parameters and return types
  2. Strict Mode Benefits

    • Enable strict: true in tsconfig.json
    • Catches more potential errors
    • Makes code more maintainable
    • Improves type safety
  3. Consistent Style

    • Use a consistent naming convention
    • Follow TypeScript coding guidelines
    • Use automated formatting tools
  4. Error Handling

    • Use type-safe error handling
    • Avoid using any type
    • Handle null and undefined explicitly

Common Pitfalls and Solutions

  1. Type Assertions
// Avoid
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
// Prefer
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
  1. Null Checking
// Use optional chaining
const value = obj?.prop?.subProp;
// Use nullish coalescing
const value = obj ?? defaultValue;
  1. Type Guards
function isString(value: any): value is string {
return typeof value === "string";
}
if (isString(value)) {
// TypeScript knows value is a string here
console.log(value.toUpperCase());
}

Conclusion

TypeScript provides a robust foundation for building scalable JavaScript applications. Its type system helps catch errors early, improves code quality, and enhances the development experience. As you continue with this series, you’ll learn more advanced features that make TypeScript a powerful tool for modern web development.

Series Navigation