The only thing you're missing is that such inference isn't currently supported. Maybe it will be in a future version of TypeScript. Luckily there is still a way to do what you want by expressing the desired operation in terms of one on function parameters, since as of TypeScript 3.0, there is a way to convert between tuple/array types and function parameters, and you can use infer as desired on parameter types.

Here's one possible implementation of Tail :

type Tail<T extends any[]> = ((...t: T) => void) extends ((x: any, ...u: infer U) => void) ? U : never; type TestTail = Tail<[1,2,3,4]>; // [2,3,4]

Notice that you take the tuple/array type T , spread it to a parameter list, then infer everything after the first parameter as another tuple/array rest type.

Similarly, you can implement your Tuple in a way that I'd call Cons :

type Cons<H, T extends any[]> = ((h: H, ...t: T) => void) extends ((...u: infer U) => void) ? U : never; type TestCons = Cons<string, [number, boolean]>; // [string, number, boolean]

And I'll leave Head as an exercise for you (that's what people say when they want to seem smart instead of lazy).

Anyway, hope that helps you make progress. Good luck!