Skip to content

Instantly share code, notes, and snippets.

@khalidx
Last active May 30, 2021 08:05
Show Gist options
  • Save khalidx/a1b00bc848067981da807773f51527c3 to your computer and use it in GitHub Desktop.
Save khalidx/a1b00bc848067981da807773f51527c3 to your computer and use it in GitHub Desktop.
A typed string splitter for TypeScript that takes 'some cool string' => ['some', 'cool', 'string']

typed-string-splitter

What the built-in string 'some cool string'.split(' ') does:

--> converts 'some cool string' to ['some', 'cool', 'string'] with a resulting type of string[]

What you can do with TypedSplit('some cool string', ' ') from this gist:

--> converts 'some cool string' to ['some', 'cool', 'string'] with a resulting type of ['some', 'cool', 'string']

Yup, a tuple type signature, with each element individually typed at its position, preserving types, instead of just 'some cool string' to string[], which loses the type signature of the parts of the string.

Here's the code. Just drop it in a TypeScript project.

type TypedSplitString <Str extends string, Separator extends string> =
  Str extends `${infer Head}${Separator}${infer Tail}`
  ? [Head, ...TypedSplitString<Tail, Separator>]
  : [Str]

function TypedSplit <Str extends string, Separator extends string> (str: Str, separator: Separator) {
  return str.split(separator) as TypedSplitString<Str, Separator>
}

PS If you don't know why this is awesome, you should TypeScript some more then come back here, possibly to appreciate this art 🤷. If you do know why this is awesome, do show me a way to make this better!

Here's an example of calling the function we defined above.

const example = TypedSplit('planets', 'net')
  // => type signature: function TypedSplit<"planets", "net">(str: "planets", separator: "net"): ["pla", "s"]
  // => returns: ["pla", "s"]

Notice how the type system knows the result of the split string, even before we call the function to actually split the string! Also, the type equals the resulting value, not a generic Array<string>.

Read more about this sort of stuff in TypeScript:

// Template literals can be used to extract and manipulate string literal types.
// These string literal types, in turn, can be used as properties, and can describe
// possible transformations from ...

TypeScript Playground Link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment