”;
Template string literals are used to create dynamic strings with variables in JavaScript. Similarly, in TypeScript you can use template literal types to create the dynamic types, which is introduced in the TypeScript 4.1 version. The syntax of the template literal types in TypeScript is very similar to the JavaScript template string literals.
Syntax
You can follow the syntax below to use the template literal types in TypeScript.
type type_name = `some_text ${variable_name}`
-
In the above syntax, ”type_name” is the name of the type.
-
You need to use the backticks (“) to define template literal types.
-
The ”some_text” can be any string value that will remain constant.
-
To add any dynamic value in the type, you need to add the variable name inside the ”${}” structure.
Examples
Let”s understand the Template Literal Types in details with the help of some examples in TypeScript.
Example: Basic Use
In the code below, we have defined the ”World” type which contains the “World” as a value. The ”Greeting” type is a template literal type whose value changes based on the value of the ”World” variable.
Next, we created the ”greeting” variable of type ”Greeting” which contains a “Hello World” value. If we try to assign another value to it, the TypeScript compiler throws an error.
type World = "world"; // Defining a template literal type type Greeting = `Hello, ${World}`; const greeting: Greeting = "Hello, world"; // Correct // const wrongGreeting: Greeting = "Hello, everybody"; // Error: This type is "Hello, world" specifically. console.log(greeting);
On compiling, it will generate the following JavaScript code:
const greeting = "Hello, world"; // Correct // const wrongGreeting: Greeting = "Hello, everybody"; // Error: This type is "Hello, world" specifically. console.log(greeting);
The above example code will produce the following output:
Hello, world
Example: Combining with Union Types
In this code, the ”size” type contains the union of multiple type values. The ”ResponseMessage” type is a template literal type whose value changes based on the value of the ”Size” type.
The selectSize() function takes a string of type ”Size” as a parameter, and returns the value of type ”ResponseMessage”.
Next, we call the function by passing ”medium” as a function parameter. If we try to pass any other string value than the ”small”, ”medium”, and ”large” as a function parameter, it will throw an error.
// Creating a type using literal type type Size = "small" | "medium" | "large"; // Custom template literal type type ResponseMessage = `${Size} size selected`; // Function to select size function selectSize(size: Size): ResponseMessage { return `${size} size selected`; } // Call the function const response: ResponseMessage = selectSize("medium"); // "medium size selected" console.log(response);
On compiling, it will generate the following JavaScript code:
// Function to select size function selectSize(size) { return `${size} size selected`; } // Call the function const response = selectSize("medium"); // "medium size selected" console.log(response);
Its output is as follows:
medium size selected
Example: Conditional String Patterns
In this example, we have used the generic types with constraints. Here, ”T extends Status” means, the value of T can be only from the status. The statusMessage type is a combination of the type ”T” and ”status” strings.
The printStatus() function takes the type T as a parameter, which can be any one value from the ”Status” type, and returns the value of type ”statusMessage”.
Next, we have called the printStatus() function by passing the “loading” value which is a part of the ”Status” type.
// Definition of the Status type type Status = "loading" | "success" | "error"; // T can be any of the values in the Status type type StatusMessage<T extends Status> = `${T}Status`; // Function to return a message based on the status function printStatus<T extends Status>(status: T): StatusMessage<T> { return `${status} Status` as StatusMessage<T>; } // Call the function with the "loading" status const loadingMessage = printStatus("Loading"); // "loadingStatus" console.log(loadingMessage);
On compiling, it will generate the following JavaScript code:
// Function to return a message based on the status function printStatus(status) { return `${status} Status`; } // Call the function with the "loading" status const loadingMessage = printStatus("Loading"); // "loadingStatus" console.log(loadingMessage);
Its output is as follows:
Loading Status
Example: API Route Generation
The below example demonstrates the real-time practical use of the template literal types.
Then, We have defined the Method type which can have any value from the REST API method type. The Entity type defines the entity objects.
The getRoute() method takes the entity and method of type Entity and Method, respectively as a parameter. It returns the string value of type APIRoute after combining the entity and method values.
// Defining the Method and Entity types type Method = "get" | "post" | "delete"; type Entity = "user" | "post"; // Defining the ApiRoute type type ApiRoute = `/${Entity}/${Method}`; // Defining the getRoute function function getRoute(entity: Entity, method: Method): ApiRoute { return `/${entity}/${method}` as ApiRoute; } // Using the getRoute function const userRoute = getRoute("user", "post"); // "/user/post" console.log(userRoute);
On compiling, it will generate the following JavaScript code:
// Defining the getRoute function function getRoute(entity, method) { return `/${entity}/${method}`; } // Using the getRoute function const userRoute = getRoute("user", "post"); // "/user/post" console.log(userRoute);
Its output is as follows:
/user/post
In TypeScript, the template literal type is mainly used when you need to create dynamic types.
”;