Turns out, there is a way to trick the compiler into doing what I want
type StartsWith<T extends string, P extends string> =
T extends `${P}${infer R}`
? T extends `${infer _P extends P}${R}`
? `Prefix: ${_P}, Rest: ${R}`
: never
: never;
type Starts = '[[' | '<<';
type Z = StartsWith<"[[Text", Starts>;
// ^?type z = "Prefix: [[, Rest: Text"
type Y = StartsWith<"<<ABC", Starts>;
// ^?type Y = "Prefix: <<, Rest: ABC"