0Pricing
TypeScript Academy · Lesson

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'>; // false

Inferring 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 strings

Quick Check

Test your understanding of type-level string splitting.

Recap

You split strings entirely in types.

  • Template literal types plus infer match and capture string parts.
  • SplitOnce breaks at the first separator; recursion yields a full Split.
  • 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

  1. Parser Combinator Concepts
  2. Type-Level String Splitting
  3. Parsing with Template Literals
  4. A Mini Type-Level Route Parser
← Back to TypeScript Academy