Type-Level String Manipulation in TypeScript
This challenge explores the fascinating world of type-level programming in TypeScript, specifically focusing on string manipulation. We'll be crafting type definitions that perform operations on strings at compile time, allowing for powerful and expressive type-safe code. This is useful for validating data structures, generating types based on input, and creating highly specialized type transformations.
Problem Description
The goal is to implement a set of type-level string manipulation functions using TypeScript's advanced type system. You will be creating type aliases that take a string as input and produce a modified string based on the specified operation. The functions should operate entirely at compile time, meaning no runtime execution is involved. The challenge focuses on three core string operations:
Uppercase<T>: Converts a stringTto uppercase.Lowercase<T>: Converts a stringTto lowercase.Repeat<T, N>: Repeats a stringTNtimes, whereNis a number literal type.
Key Requirements:
- Type Safety: The solutions must be type-safe. Incorrect input types should result in TypeScript errors.
- Compile-Time Execution: All operations must be performed at compile time.
- No Runtime Code: The solution should consist solely of type definitions and should not involve any JavaScript code.
- Literal Number Types for Repetition: The
Repeatfunction must accept a number literal type (e.g.,2,5,10) for the repetition count. Using a generic number type is not acceptable.
Expected Behavior:
Uppercase<"hello">should evaluate to"HELLO".Lowercase<"WORLD">should evaluate to"world".Repeat<"abc", 3>should evaluate to"abcabcabc".- Incorrect input types (e.g., numbers, booleans) should result in TypeScript compiler errors.
Edge Cases to Consider:
- Empty strings: How should
Uppercase,Lowercase, andRepeatbehave with empty strings? (Returning an empty string is acceptable). - Strings with non-ASCII characters: Consider how Unicode characters might be handled (though full Unicode support is not required).
- Invalid repetition counts (e.g., negative numbers, non-literal numbers): The
Repeatfunction should only accept number literal types.
Examples
Example 1:
Input: Uppercase<"typescript">
Output: "TYPESCRIPT"
Explanation: The string "typescript" is converted to uppercase at the type level.
Example 2:
Input: Lowercase<"CODE">
Output: "code"
Explanation: The string "CODE" is converted to lowercase at the type level.
Example 3:
Input: Repeat<"hello", 2>
Output: "hellohello"
Explanation: The string "hello" is repeated 2 times at the type level.
Example 4: (Edge Case)
Input: Repeat<"test", 0>
Output: ""
Explanation: Repeating a string 0 times results in an empty string.
Constraints
- Number Literal Type for
Repeat: TheNtype parameter inRepeat<T, N>must be a number literal type. Using a generic number typeNis not allowed. - String Input: All functions should accept a string type as input. Attempting to pass a non-string type should result in a TypeScript error.
- No Runtime Code: The solution must be purely type-level and should not involve any JavaScript code.
- Performance: While performance isn't a primary concern in type-level programming, avoid unnecessarily complex or inefficient type manipulations. The goal is clarity and correctness.
Notes
- You'll likely need to leverage TypeScript's conditional types, mapped types, and potentially distributive conditional types to achieve the desired string manipulations.
- Consider using helper types to break down the problem into smaller, more manageable pieces.
- Think about how to handle the repetition logic in
Repeatefficiently at the type level. Recursive type definitions can be helpful. - Start with the simpler functions (
UppercaseandLowercase) before tacklingRepeat, which is more complex. - Test your solutions thoroughly with various inputs, including edge cases, to ensure type safety and correctness.