Template Literal Types

Published on

Template literal types are a relatively new feature in TypeScript, but they're already proving to be a game-changer. They allow you to create complex string types, which is incredibly useful for typing CSS-in-JS libraries, creating strongly typed event systems, and much more.

Combining Template Literal Types

The real power of template literal types comes from their ability to be combined with other types. For example, you could create a type that represents a CSS class name like this:

type Size = 'small' | 'medium' | 'large'; type ClassName = `btn-${Color}-${Size}`;

Now, the ClassName type can be any of the following strings:

  • 'btn-red-small'
  • 'btn-red-medium'
  • 'btn-red-large'
  • 'btn-green-small'
  • 'btn-green-medium'
  • 'btn-green-large'
  • 'btn-blue-small'
  • 'btn-blue-medium'
  • 'btn-blue-large'

Usage Example

This is incredibly useful for creating strongly typed CSS-in-JS libraries. For example, you could create a Button component that only accepts valid class names:

interface ButtonProps { className: ClassName; } function Button({ className }: ButtonProps) { return <button className={className}> Click me </button>; }

Now, if you try to pass an invalid class name to the Button component, you'll get a TypeScript error:

// ✅ This is valid <Button className="btn-red-small" /> // ❌ This is not valid - TypeScript will show an error <Button className="btn-yellow-small" />

Template literal types are a powerful new tool in the TypeScript toolbox. They can help you write more expressive, more type-safe, and more maintainable code.