In TypeScript 4.1 which dev version is already avalible through npm there are support for Recursive Conditional Types and Template literal types what creates some really interesting opportunities
Let's assume we have following type
// type is '0123456';
const actualString = '0123456';
Task
Split a string by characters into new array, but type of array elements should be preserved
// Unfortunately, type is string[]
const chars1 = actualString.split('');
// Throws error: string[] is not assignable ['0', '1', '2', '3', '4', '5', '6']
const chars2: ['0', '1', '2', '3', '4', '5', '6'] = actualString.split('');
My take on this one
type StringToChars<BASE extends string> = BASE extends `${infer _}`
? BASE extends `${infer FIRST_CHAR}${infer REST}` // BASE is inferable
? [FIRST_CHAR, ...StringToChars<REST>] // BASE has at least one character
: [] // BASE is empty string
: string[]; // BASE is simple string
// type is ['0', '1', '2', '3', '4', '5', '6']
type Chars = StringToChars<'0123456'>;
Problem
This solution works fine for strings lesser than 14 chars.
// Throws: Type instantiation is excessively deep and possibly infinite. (ts2589)
type LargeCharsArray = StringToChars<'0123456789 01234'>
Obviously it runs into typescript types recursion limit, after checking on 14th char it leaves us with [<first 14 characters>, ...any[]].
Question
This recursive type call looks really bad, so I was wondering, is there more reliable way to transform string type into array of chars type?