Given a strongly-typed tuple created using a technique such as described here:
const tuple = (...args: T) => args;
const furnitu
I have other proposition
type RemoveFirstFromTuple =
T extends [] ? undefined :
(((...b: T) => void) extends (a: any, ...b: infer I) => void ? I : [])
const tuple = (...args: T) => args;
type FurnitureUnion = 'chair' | 'table' | 'lamp';
type FurnitureTuple = ['chair', 'table' , 'lamp'];
type Check> = {
"error": never,
"next": Check>,
"exit": true,
}[Tuple extends [] ? "exit" : Tuple[0] extends Union ? "next" : "error"];
type R = Check; // true
type R1 = Check<'chair' | 'lamp' | 'table', FurnitureTuple>; // true
type R2 = Check<'chair' | 'lamp' | 'table', ['chair', 'table' , 'lamp', 'error']>; // nerver
Remove from tuple takes tuple and return tuple without first element (will be needed later)
Check will iterate on Tuple. Each step can return never when Tuple[0] don't extend Union, exit when input tuple is empty and next when Tuple[0] extends Union. In next step we recursive call Check but first we remove first element from Tuple by previous util
Playground