Type-Level String Splitting
Split strings into tuples within the type system.
Type-Level String Splitting is a free TypeScript Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Template Literal Types
The type system can pattern-match on string literal types using template literal types combined with infer. This is the core tool for type-level string parsing.
Notation: real TypeScript writes template literal types with backtick-delimited strings containing dollar-brace holes. In these snippets we show that pattern as Tpl<...>, listing each part in order; e.g. a backtick template matching the literal prefix then Rest appears as Tpl<'prefix', infer Rest>.
type StartsWithA<S> = S extends Tpl<'a', string> ? true : false;
// Tpl<'a', string> is a backtick template literal type: 'a' then anything
type X = StartsWithA<'abc'>; // true
type Y = StartsWithA<'bcd'>; // falseInferring a Suffix
Place infer inside the template to capture part of the string. Here we capture everything after a leading "a".
type AfterA<S> = S extends Tpl<'a', infer Rest> ? Rest : never;
// Tpl<'a', Rest> captures everything after a leading 'a'
type X = AfterA<'abc'>; // 'bc'Splitting on a Delimiter
To split a string at the first occurrence of a separator, match the pattern "head, separator, tail" and infer both sides. The first match wins because inference is greedy from the left for the head.
type SplitOnce<S, Sep extends string> =
S extends Tpl<infer Head, Sep, infer Tail>
? [Head, Tail]
: [S];
// Tpl<Head, Sep, Tail> matches up to the first separator
type X = SplitOnce<'a-b-c', '-'>; // ['a', 'b-c']Recursive Split
To split into all parts, recurse on the tail. Collect each head into a tuple until no separator remains.
type Split<S extends string, Sep extends string> =
S extends Tpl<infer Head, Sep, infer Tail>
? [Head, ...Split<Tail, Sep>]
: [S];
// recurse on Tail until no separator remains
type X = Split<'a.b.c', '.'>; // ['a', 'b', 'c']Walking the Recursion
Trace Split<"a.b.c", ".">:
- Head "a", Tail "b.c" -> ["a", ...Split<"b.c">]
- Head "b", Tail "c" -> ["b", ...Split<"c">]
- "c" has no ".", base case -> ["c"]
Result: ["a", "b", "c"].
type X = Split<"one,two", ",">; // ["one", "two"]
type Y = Split<"x/y/z", "/">; // ["x", "y", "z"]Handling Empty Segments
Splitting can produce empty strings when separators are adjacent or at the edges. The pattern still matches, inferring an empty Head or Tail.
type X = Split<"a,,b", ",">; // ["a", "", "b"]
type Y = Split<",a", ",">; // ["", "a"]Joining Back
The inverse of split is join: walk a tuple of strings and concatenate with a separator using a template literal. This pairs naturally with split.
type Join<T extends string[], Sep extends string> =
T extends [infer H extends string, ...infer R extends string[]]
? R extends [] ? H : Tpl<H, Sep, Join<R, Sep>>
: '';
// Tpl<...> denotes a template literal type concatenation
type X = Join<['a', 'b', 'c'], '-'>; // 'a-b-c'Trimming Whitespace
String utilities compose. A Trim type removes leading and trailing spaces by repeatedly stripping a space via template inference.
type TrimLeft<S extends string> =
S extends Tpl<' ', infer R> ? TrimLeft<R> : S;
type TrimRight<S extends string> =
S extends Tpl<infer R, ' '> ? TrimRight<R> : S;
type Trim<S extends string> = TrimRight<TrimLeft<S>>;
// Tpl<' ', R> strips a leading space; Tpl<R, ' '> strips a trailing one
type X = Trim<' hi '>; // 'hi'Replacing Substrings
Replace works by splitting around the target and rejoining with the replacement, all via template inference and recursion.
type ReplaceAll<S extends string, From extends string, To extends string> =
S extends Tpl<infer A, From, infer B>
? Tpl<A, To, ReplaceAll<B, From, To>>
: S;
// split around From, then rejoin with To via template literal types
type X = ReplaceAll<'a-b-c', '-', '_'>; // 'a_b_c'Why Splitting Matters
Splitting is the foundation of structured parsing. Routes split on "/", query strings split on "&", CSV rows split on ",". With Split you turn a flat string type into a tuple you can process element by element.
type Segments = Split<"users/42/posts", "/">; // ["users", "42", "posts"]Caution on Depth
Type-level string recursion is bounded by the compiler depth limit. Very long strings or many separators can exceed it. For typical inputs (paths, small formats) it works smoothly.
type Ok = Split<"a/b/c/d/e", "/">; // fine for small stringsQuick Check
Test your understanding of type-level string splitting.
Recap
You split strings entirely in types.
- Template literal types plus
infermatch and capture string parts. SplitOncebreaks at the first separator; recursion yields a fullSplit.- Join, Trim, and ReplaceAll compose from the same tools.
Next: extracting structured data from string types.
Frequently asked questions
Is the “Type-Level String Splitting” lesson free?
Yes — the full text of “Type-Level String Splitting” is free to read here on the web, and the TypeScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.
What will I learn in “Type-Level String Splitting”?
Split strings into tuples within the type system. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start TypeScript Academy?
No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Type-Level String Splitting” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this TypeScript Academy lesson?
Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Parser Combinator Concepts
- Type-Level String Splitting
- Parsing with Template Literals
- A Mini Type-Level Route Parser