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'
tostring[]
, 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