DEV Community

Dharan Ganesan
Dharan Ganesan

Posted on

Day 50: Template Literal Types

What Are Template Literal Types?

Template literal types are a TypeScript feature introduced in version 4.1. They allow you to create complex types by interpolating or transforming string literals. These types can be used for a wide range of applications, from modeling data shapes to generating more specific error messages.

The basic syntax of a template literal type looks like this:

type MyType = `Hello, ${string}!`;
Enter fullscreen mode Exit fullscreen mode

Here, ${string} is a placeholder that can be replaced with any string literal.

Now, let's delve into some examples.

String Enums

Template literal types can simplify the creation of string enums. Consider the following:

type Fruit = "Apple" | "Banana" | "Orange";
Enter fullscreen mode Exit fullscreen mode

This defines a type Fruit that can only have one of three specific string values. With template literal types, you can achieve the same result more dynamically:

type Fruit<T extends string> = `${T} is a fruit`;
let apple: Fruit<"Apple">; // Results in  "Apple is a fruit"
Enter fullscreen mode Exit fullscreen mode

URL Building

Imagine you're working with a REST API, and you want to create type-safe URL builders for different endpoints. Template literal types can help with that too:

type Endpoint = "users" | "posts" | "comments";

type UrlBuilder<T extends Endpoint> = `https://api.example.com/${T}`;

let usersUrl: UrlBuilder<"users">; // Results in "https://api.example.com/users"
Enter fullscreen mode Exit fullscreen mode

Error Messages

Template literal types can enhance error messages by providing more context:

type ErrorMsg<T extends string> = `Error: ${T} not found`;

function throwError<T extends string>(msg: ErrorMsg<T>): never {
  throw new Error(msg);
}

throwError("User");
Enter fullscreen mode Exit fullscreen mode

Here, the throwError function ensures that the error message is in the format "Error: [Your Message] not found". This not only helps with consistency but also makes debugging easier.

Pluralization

Let's say you want to pluralize words in a type-safe way:

type Pluralize<Singular extends string> = `${Singular}s`;

type Apples = Pluralize<"Apple">; // Results in "Apples"
type Bananas = Pluralize<"Banana">; // Results in "Bananas"
Enter fullscreen mode Exit fullscreen mode

By using template literal types, you can create a Pluralize type that automatically pluralizes any singular noun.

Why Use Template Literal Types?

Template literal types offer several advantages:

  1. String Manipulation: They enable string manipulation within type definitions, making it easier to create precise types that reflect your data or intentions.

  2. Readability: By embedding string literals directly into type definitions, your code becomes more self-documenting, making it easier for other developers (and your future self) to understand.

  3. Autocompletion: IDEs can provide autocompletion for template literal types, which can significantly speed up development.

  4. Type Safety: Since TypeScript checks these types at compile-time, you can catch errors early, reducing runtime issues.

  5. Dynamic Types: Template literal types can generate dynamic types based on input values, which is incredibly useful when working with APIs or data transformations.

Top comments (0)