TypeScript String Interpolation: A Complete Guide to Template Literals
TypeScript string interpolation uses backtick-delimited template literals with ${expression} placeholders, which the compiler transforms into string concatenations for ES5 targets or preserves as native template literals for ES2015+ output.
TypeScript provides robust support for string interpolation through ECMAScript template literals, enabling developers to embed expressions directly within string literals. This feature is implemented in the microsoft/TypeScript repository and handles everything from simple variable substitution to complex tagged template transformations.
How TypeScript String Interpolation Works
TypeScript string interpolation relies on template literals enclosed by backticks (`). Within these literals, expressions wrapped in ${} act as placeholders that get evaluated at runtime.
When the TypeScript compiler processes these literals, it creates specific AST nodes to represent the structure:
TemplateExpressionnodes represent the overall template literalTemplateHeadnodes capture the text before the first placeholderTemplateSpannodes pair each expression with the following literal textTemplateMiddleandTemplateTailnodes handle intermediate and final text segments
These node definitions reside in src/compiler/types.ts (lines 5051-5062), where the TypeScript compiler defines the structural representation of template literals for type checking and emit purposes.
TypeScript String Interpolation Syntax and Examples
Basic Variable Interpolation
The most common use case involves embedding variables directly into strings:
const name = "Alice";
const age = 30;
// Template literal with string interpolation
const greeting = `Hello, ${name}! You are ${age} years old.`;
console.log(greeting);
// → Hello, Alice! You are 30 years old.
When targeting ES5, the compiler transforms this into string concatenation operations. The createTemplateExpression function in src/compiler/factory/nodeFactory.ts (lines 3509-3525) generates the factory methods used to construct these concatenation expressions during emit.
The ES5 output looks like:
var name = "Alice";
var age = 30;
var greeting = "Hello, " + name + "! You are " + age + " years old.";
console.log(greeting);
Tagged Template Literals
TypeScript supports tagged templates, where a function processes the literal parts and interpolated values separately:
function highlight(strings: TemplateStringsArray, ...values: any[]) {
// Insert <em> around each interpolated value
return strings.reduce((result, str, i) =>
result + str + (i < values.length ? `<em>${values[i]}</em>` : ""), "");
}
const user = "Bob";
const msg = highlight`User ${user} logged in.`;
console.log(msg);
// → User <em>Bob</em> logged in.
The parser in src/compiler/parser.ts (lines 3660-3680) handles the tokenization of template heads, spans, and tails when building the AST for tagged templates. The tag function receives the raw string array and the evaluated expressions as separate arguments, allowing for custom formatting, localization, or sanitization logic.
Interpolating Non-String Values
TypeScript automatically converts interpolated values to strings using the String() constructor:
const arr = [1, 2, 3];
const info = `Array length: ${arr.length}, first: ${arr[0]}`;
console.log(info);
// → Array length: 3, first: 1
The type checker ensures that expressions within ${} are valid, though any value convertible to string (which includes most JavaScript values) is acceptable. For ES5 targets, the emitter explicitly wraps expressions in String() calls when necessary to ensure proper coercion.
Compiler Implementation Details
Understanding how TypeScript processes string interpolation requires examining three critical source files:
| File | Role | Key Components |
|---|---|---|
src/compiler/types.ts |
AST node definitions | TemplateExpression, TemplateHead, TemplateSpan, TemplateMiddle, TemplateTail |
src/compiler/parser.ts |
Syntax analysis | Template literal tokenization (lines 3660-3680) |
src/compiler/factory/nodeFactory.ts |
Code generation | createTemplateExpression for ES5 transform (lines 3509-3525) |
When targeting ES2015 or later, TypeScript preserves template literals as-is, allowing the JavaScript engine to handle interpolation at runtime. When targeting ES5 or ES3, the compiler decomposes the template into a series of binary + operations and String() calls, ensuring compatibility with older environments while maintaining identical runtime behavior.
Summary
- TypeScript string interpolation uses backtick-delimited template literals with
${expression}placeholders. - The compiler creates
TemplateExpressionAST nodes defined insrc/compiler/types.tsto represent these literals. - For ES2015+ targets, template literals emit unchanged; for ES5, they transform into string concatenations via
createTemplateExpressioninsrc/compiler/factory/nodeFactory.ts. - Tagged templates allow custom processing of literal parts and values, parsed in
src/compiler/parser.ts. - Any expression convertible to string can be interpolated, with automatic coercion handled by the compiler or runtime.
Frequently Asked Questions
How do I escape backticks in a TypeScript template literal?
To include a literal backtick character inside a template literal, escape it with a backslash: \`. For example: const str = `Use \`code\` tags`; produces the string Use code tags. Dollar signs can be escaped as \$ to prevent interpolation if you need the literal ${ sequence.
Can I use TypeScript string interpolation with internationalization (i18n)?
Yes, tagged template literals are ideal for i18n. You define a tag function that looks up translations based on the template structure, passing the literal strings and interpolated values separately. This allows the function to reorder values for different languages or wrap them in markup while preserving type safety. The TypeScript compiler preserves the tagged template structure in the output (or transforms it appropriately for ES5).
What is the performance difference between template literals and string concatenation?
At runtime in modern JavaScript engines, template literals and string concatenation using + have nearly identical performance characteristics because engines optimize both similarly. However, TypeScript's ES5 emit for template literals generates multiple + operations and potential String() coercion calls, which could be slightly less optimal than hand-written concatenation in very hot paths. For ES2015+ targets, the emitted code matches the source template literal exactly, incurring no additional overhead.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →