TypeScript Keywords

TypeScript extends the capabilities of JavaScript by introducing a rich set of proprietary keywords. These keywords are the building blocks used to define complex types, perform sophisticated type computations, and implement robust object-oriented patterns. Mastering these terms is not merely about learning syntax; it is about understanding how to leverage the TypeScript compiler to write code that is self-documenting, type-safe, and highly maintainable.

To better understand how to use these tools, we can categorize them into four functional groups: Type Definition, Type Manipulation, Class-related features, and Declaration/Environment management.
The foundation of any TypeScript project lies in how data structures are defined. TypeScript provides three primary ways to describe the "shape" of data:

  • type: Used to create type aliases. A type alias can represent anything from a simple primitive to complex structures like union types, intersections, tuples, and function signatures. It is highly flexible and often used when you need to combine multiple types.
  • interface: Specifically designed to describe the structure of an object. Unlike type aliases, interfaces support declaration merging (where multiple declarations of the same interface name merge into one) and are the preferred way to define API contracts and class structures.
  • enum: Allows you to define a set of named constants. Enums make code more readable and intent-driven by grouping related values together under a single name.
// Using type for a union of primitives
type ID = string | number;

// Using interface to describe an object structure
interface User {
  readonly id: number; // Prevents modification after initialization
  name: string;
}

// Using enum to organize related constants
enum Direction {
  Up,
  Down,
  Left,
  Right,
}

Advanced Type Manipulation

One of TypeScript's most powerful features is its ability to perform "logic" at the type level. These keywords allow developers to transform existing types into new ones, creating highly dynamic and reusable type systems.

  • keyof: An index type query operator that takes an object type and produces a union of its keys.
  • typeof: In a type context, this operator allows you to extract the type of a specific variable or expression.
  • in: Used within mapped types to iterate over the keys of an existing type, allowing you to create new types based on the properties of another.
  • infer: A keyword used within conditional types to infer a type from within another type, acting much like a variable declaration within a type logic block.
  • as: Primarily used for type assertions (telling the compiler "trust me, I know what this is"). In the context of mapped types, it can also be used for key remapping.
  • is: A type predicate used in user-defined type guards. It allows a function to return a boolean that also informs the compiler about the specific type of a variable within a conditional block.
  • satisfies: Introduced in TS 4.9, this operator validates that an expression matches a specific type without changing the resulting type of that expression. This allows you to keep the most specific type information possible while still ensuring type safety.
type UserKeys = keyof User; // Results in: "id" | "name"

// Using 'in' and 'keyof' to create a Partial type
type PartialUser = { [K in keyof User]?: User[K] };

// Using 'is' for a custom type guard
function isUser(v: unknown): v is User {
  return typeof v === "object" && v !== null && "id" in v;
}

// Using 'satisfies' to validate while preserving precision
const conf = {
  host: "localhost",
  port: 8080,
} satisfies Record<string, string | number>;

Object-Oriented Programming (OOP) Keywords

TypeScript brings enterprise-grade OOP features to the JavaScript ecosystem, providing fine-grained control over how class members are accessed and inherited.

Access Modifiers and Member Control

  • public: The default modifier. Members are accessible from anywhere.
  • private: Members are only accessible within the class they are defined in.
  • protected: Members are accessible within the class and its subclasses.
  • readonly: Ensures that a property can only be assigned a value during its declaration or within the class constructor.
  • static: Defines members that belong to the class itself rather than to instances of the class.

Inheritance and Abstraction

  • abstract: Used to define abstract classes or methods. An abstract class cannot be instantiated directly and serves as a blueprint for other classes.
  • extends: Used in class declarations to implement inheritance, allowing a subclass to inherit properties and methods from a parent class.
  • implements: Used to ensure a class adheres to a specific interface contract.
  • override: A safety feature that explicitly marks a method as an intentional override of a parent class member, helping to catch errors if the parent method name changes.
interface Pet {
  play(): void;
}

abstract class Animal {
  protected name: string;
  constructor(name: string) {
    this.name = name;
  }
  abstract makeSound(): void; // Must be implemented by subclasses
}

class Dog extends Animal implements Pet {
  constructor(name: string) {
    super(name);
  }

  override makeSound(): void {
    console.log("Woof!");
  }

  play(): void {
    console.log("Playing...");
  }
}

Declaration and Environment Keywords

Sometimes, you need to interact with code that TypeScript doesn't "see," such as global variables from a CDN or legacy JavaScript libraries.

  • declare: Used in ambient declarations. It tells the compiler that a variable, function, or class already exists in the environment (e.g., in a global script or a third-party library), so the compiler should not throw an error, even though it won't generate any JavaScript code for it.
  • namespace: A way to group related code together to avoid global scope pollution. While still present in the language, modern development favors ES Modules for code organization.
  • as const: Known as a const assertion. It tells TypeScript to treat an entire object or array as a literal, deeply immutable type, preventing any property from being widened to a general type.

By mastering these keywords, you transition from simply "writing code that works" to "designing systems that are mathematically sound and architecturally robust."