All Articles

What are Interfaces in TypeScript, and When Should you use Them

Joe PreviteJoe Previte

Interfaces: one of the most used types in everyday TypeScript. Knowing what it is and how to use it is important to becoming a proficient TypeScript developer and writing production-ready code.

By learning what they are and how to use them in the real world, you’ll be able to start contributing to TypeScript codebases much faster. You might even learn a trick or two to show off to a friend!

Show me the code

If you want to jump straight into code examples, take a look at these TypeScript playground links:

Interfaces Explained using Twitter

When I learn something new, I always try to connect it to something I already know. That way, it’s easier for my brain to remember it.

Let’s try to understand Interfaces using something we’re all familiar with: tweets.

What is a tweet exactly? Well, it’s a social media post that may contain text and/or images/videos. When we look at how tweets are represented as data according to the Twitter API spec, they look something like this:

{
  "id": "1212092628029698048",
  "text": "We believe the best future version of our API will come from building it with YOU. Here’s to another great year with everyone who builds on the Twitter platform. We can’t wait to continue working with you in the new year. https://t.co/yvxdK6aOo2",
  "referenced_tweets": [
    {
      "type": "replied_to",
      "id": "1212092627178287104"
    }
  ],
  "author_id": "2244994945",
  "public_metrics": {
    "retweet_count": 8,
    "reply_count": 2,
    "like_count": 40,
    "quote_count": 1
  },
  "lang": "en",
  "created_at": "2019-12-31T19:26:16.000Z",
  "source": "Twitter Web App",
  "in_reply_to_user_id": "2244994945",
  "attachments": {
    "media_keys": ["16_1211797899316740096"]
  }
}
😎Reflection

NOTE: this structure has been slimmed down for the purpose of the explanation. See the Twitter API tweet object to see all properties on the tweet object.

Okay, so what’s an interface? It’s a way to describe the shape of a data structure. In this case, we can represent "public_metrics" as an interface called PublicMetrics:

interface PublicMetrics {
  retweet_count: number;
  reply_count: number;
  like_count: number;
  quote_count: number;
}

You can view here on the TypeScript Playground.

As you can see, the interface lets you know the shape of the structure. With PublicMetrics, we know it has four properties which are all of type number. Very helpful when receiving this information from an API and then displaying it on the frontend.

But this isn’t the best example to showcase TypeScript. Why? You’d have to maintain these interfaces on both the client-side and the server-side, so you’d have duplicated types. Instead, there are tools like tRPC that can generate these types from the API for you.

Let’s look at another Twitter-inspired example:

interface TweetInput {
  text: string;
  /** a list of URLs that point to images, videos or gifs. */
  attachments: undefined | string[];
}

interface Tweet extends TweetInput {
  createdAt: Date;
}

function createTweet(input: TweetInput): Tweet {
  return {
    text: input.text,
    attachments: input.attachments,
    createdAt: new Date(),
  };
}

You can view it here on the TypeScript Playground.

As you can see, we can use an interface to define what a function takes in (Parameter Type Annotation) and what it returns (Return Type Annotation).

You can think of Interfaces like contracts. They are used to ensure data structures are used according to their shapes.

You may also notice /** comment */ used in the first interface. That’s a TSDoc comment, which is helpful when you want to give more information about a type. I believe it’s good practice to use them when things might not be obvious. In our case, our team members will know this is not just any string, but URL strings that point to image-like attachments related to the tweet.

Interfaces in the Wild

We’ve discussed hypothetical Interfaces, but now let’s look at some in the wild. What does an Interface in an open source project look like?

Here’s one from a project called code-server which is VS Code for the web:

/**
 * Code flags provided by the user.
 */
export interface UserProvidedCodeArgs {
  "disable-telemetry"?: boolean;
  force?: boolean;
  "user-data-dir"?: string;
  "enable-proposed-api"?: string[];
  "extensions-dir"?: string;
  "builtin-extensions-dir"?: string;
  "install-extension"?: string[];
  "uninstall-extension"?: string[];
  "list-extensions"?: boolean;
  "locate-extension"?: string[];
  "show-versions"?: boolean;
  category?: string;
  "github-auth"?: string;
  "disable-update-check"?: boolean;
  "disable-file-downloads"?: boolean;
}

You can view it here on the TypeScript Playground or view the source on GitHub here.

These are a list of flags that can be passed to the code-server CLI. As you can see, all of these are optional because they have the ? after each key. This is a great example of an Interface in the wild because:

  • it’s not too complex
  • it uses readable names
  • it has a comment describing what it does

Recommendation: spend five minutes looking for other Interface examples in the code-server codebase until you feel comfortable knowing what they are and how they’re used.

Resources

For more in-depth info on interfaces, take a look at the TypeScript handbook section here. I also want to give a shout-out to Ryan Waits for the inspiration. When he was teaching others Solidity, he used real-world examples like tweets and that’s where this idea originated.

Summary

As we saw today, Interfaces are used to describe the shape of things. We used some hypothetical examples in the context of Twitter. Then we dove into the wild west of open source on GitHub and looked at a real-world example in a popular open source project.

Play around with Interfaces and get comfortable with them. They’re a great tool for writing production-ready TypeScript, and one you want to be familiar with.