TypeScript Academy · Lesson

Type-Level String Splitting

Split strings into tuples within the type system.

Lesson 2 of 413 steps

Type-Level String Splitting is a free TypeScript Academy lesson on CoddyKit. This is 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, and your progress syncs across the web and the CoddyKit app. The TypeScript Academy course includes 4 lessons in total.

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.

Free to start

Learn TypeScript with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
101
Lessons
352

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. 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. The TypeScript Academy course includes 4 lessons in total.

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, so you can start here or from the beginning and move at your own pace. This is lesson 2 of 4.

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