Hone logo
Hone
Problems

Crafting Dynamic String Types with Template Literals

TypeScript's template literal types empower you to create highly dynamic and type-safe string unions. This challenge will test your understanding of how to build and manipulate these types to represent complex string patterns, which is invaluable for scenarios like API endpoint definitions, event naming conventions, or internationalization keys.

Problem Description

Your task is to create a set of TypeScript template literal types that can accurately represent different variations of a string format. Specifically, you need to define types that can handle strings following the pattern: [prefix]-[key]-[suffix], where prefix, key, and suffix can each be one of several predefined literal string values.

Key Requirements:

  1. Define Literal Unions: Create distinct type aliases for the possible values of prefix, key, and suffix.
  2. Construct Template Literal Types: Combine these literal unions using TypeScript's template literal type syntax to form the final string type.
  3. Handle All Combinations: The final type should encompass all valid combinations of prefixes, keys, and suffixes.
  4. Type Safety: Ensure that any string assigned to a variable with this type adheres to the defined pattern and allowed literal values.

Expected Behavior:

Your types should allow variables to be assigned strings that strictly follow the prefix-key-suffix format, using only the predefined allowed values for each part. Attempts to assign strings that deviate from this format or use invalid literal values should result in a TypeScript compilation error.

Important Edge Cases:

  • Consider the order of the literal unions within the template literal.
  • Ensure the hyphen separators are correctly included.

Examples

Example 1:

// Let's say our allowed prefixes are 'api', 'data', 'user'
// Our allowed keys are 'get', 'post', 'delete'
// Our allowed suffixes are 'list', 'item', 'details'

// A valid string would be: 'api-get-list'
// Another valid string: 'user-delete-item'

// Invalid strings (would cause TypeScript errors):
// 'api-get-users' (invalid suffix)
// 'api-get_list' (invalid separator)
// 'service-get-list' (invalid prefix)

Example 2:

Let's define the specific types:

type Prefixes = 'api' | 'data' | 'user';
type Keys = 'get' | 'post' | 'delete';
type Suffixes = 'list' | 'item' | 'details';

// Your main type alias should go here
// type MyDynamicString = ...

// --- Usage ---
const validString1: MyDynamicString = 'api-get-list'; // Should be valid
const validString2: MyDynamicString = 'user-post-item'; // Should be valid
const validString3: MyDynamicString = 'data-delete-details'; // Should be valid

// const invalidString1: MyDynamicString = 'api-put-list'; // Should be an error
// const invalidString2: MyDynamicString = 'api-get-single'; // Should be an error
// const invalidString3: MyDynamicString = 'auth-get-list'; // Should be an error
// const invalidString4: MyDynamicString = 'api-get-list-v2'; // Should be an error (extra part)

Constraints

  • The number of possible values for Prefixes, Keys, and Suffixes will be between 2 and 5 for each category.
  • The input to your type definition will be the three literal union types as shown in Example 2.
  • There are no explicit performance constraints for type checking.

Notes

  • Remember that template literal types in TypeScript allow you to embed existing types (including unions) within a string literal pattern.
  • Think about how you can combine your defined literal unions within the ${Type1}-${Type2}-${Type3} syntax.
  • The goal is to create a single, comprehensive type that represents all valid combinations.
Loading editor...
typescript