Using Interfaces for Type Declarations

In TypeScript, we can also use interfaces to define object types. Interfaces are similar to type aliases but differ in how they can be extended and implemented. For most use cases, the two are interchangeable, so you can choose whichever fits your coding style.

I prefer interfaces for defining object types because I can use the extends keyword to create subtypes. This is a familiar concept if you have worked with object-oriented languages. Type aliases are more like sets of types that we can combine with the union (|) or intersection (&) operators.

Let’s rewrite our earlier type definitions using interfaces:

interface Definition {
  definition: string;
  example?: string;
  synonyms?: string[];
  antonyms?: string[];
}

interface Meaning {
  partOfSpeech: string;
  definitions: Definition[];
}

interface Phonetic {
  text?: string;
  audio?: string;
}

interface DictionaryAPIResponse {
  word: string;
  phonetic?: string;
  phonetics: Phonetic[];
  origin?: string;
  meanings: Meaning[];
}

Notice the syntax: interface InterfaceName { /* ... */ }. Properties are defined the same way as with type aliases: a property name followed by a colon (:) and its type.

There are only two syntactic differences between type aliases and interfaces:

  1. Type aliases use the type keyword; interfaces use the interface keyword.
  2. Type aliases use = to assign a type (e.g., type Foo = { ... }), while interfaces define their structure directly with { ... } without an = sign.

In the next steps, we will annotate every function parameter and return value with the appropriate types.

Checkpoint: Commit your progress.

git add .
git commit -m "dictionary-03: Use interfaces for type declarations"
git push