Template literal types

String types built from templates, like `${A}-${B}`.

On this page

Example

#
TypeScript
type Size = 'sm' | 'md' | 'lg'
type Variant = 'primary' | 'ghost'
type ButtonClass = `btn-${Variant}-${Size}`
// type ButtonClass = "btn-primary-sm" | "btn-primary-md" | ... (6 combinations)

function buttonClass(variant: Variant, size: Size): ButtonClass {
  return `btn-${variant}-${size}`
}

console.log(buttonClass('primary', 'lg'))
Result
btn-primary-lg

Definition and usage

#

Template literal types use JavaScript’s template syntax, but at the type level. `btn-${Size}` with Size = "sm" | "lg" gives the union "btn-sm" | "btn-lg". The compiler expands every combination.

This lets you precisely type CSS class names, event names, translation keys, or paths. A typo in a string like that gets caught right away.

TypeScript also has built-in types for changing letter case: Uppercase, Lowercase, Capitalize, and Uncapitalize, which come in handy combined with templates.

Syntax

#
Syntax
type Name = `prefix-${Type}`

More examples

#
Event names
TypeScript
type Field = 'email' | 'password'
type ChangeEvent = `${Field}Changed`
// type ChangeEvent = "emailChanged" | "passwordChanged"

const event: ChangeEvent = 'emailChanged'
console.log(event)
Result
emailChanged

Good practices

#
  • With large unions, the number of combinations grows fast. Too many combinations slow the compiler down.
  • Template literal types work great for translation keys, e.g. `nav_${string}`.

Related entries

#

Spotted a mistake or missing an example? Write to us.