DEV Community

Discussion on: How 2 TypeScript: Get the last item type from a tuple of types

Collapse
 
kjleitz profile image
Keegan Leitz

Hey! Great article. In case it's useful, I figured out a way to get the length - 1 of an arbitrary-length tuple, so you're no longer limited to the hard-coded breadth of Prev<T>! Check it out:

// Gets the length of an array/tuple type. Example:
//
//   type FooLength = LengthOfTuple<[string, number, boolean]>;
//   //=> 3
//
export type LengthOfTuple<T extends any[]> = T extends { length: infer L } ? L : never;

// Drops the first element of a tuple. Example:
//
//   type Foo = DropFirstInTuple<[string, number, boolean]>;
//   //=> [number, boolean]
//
export type DropFirstInTuple<T extends any[]> = ((...args: T) => any) extends (arg: any, ...rest: infer U) => any ? U : T;

// Gets the type of the last element of a tuple. Example:
//
//   type Foo = LastInTuple<[string, number, boolean]>;
//   //=> boolean
//
//   function lastArg<T extends any[]>(...args: T): LastInTuple<T> {
//     return args[args.length - 1];
//   }
//
//   const bar = lastArg(1);
//   type Bar = typeof bar;
//   //=> number
//
//   const baz = lastArg(1, true, "hey", 123, 1, 2, 3, 4, 5, 6, 7, -1, false);
//   type Baz = typeof baz;
//   //=> boolean
//
export type LastInTuple<T extends any[]> = T[LengthOfTuple<DropFirstInTuple<T>>];
Enter fullscreen mode Exit fullscreen mode
Collapse
 
mattmcmahon profile image
Matt McMahon

This magic spell has just saved me a bunch of headache. Thanks, Keegan!

Collapse
 
menocomp profile image
Mina Luke

Interesting I like the way you removed the first item from the tuple.
It can be simplified more by doing this:

type DropFirstInTuple<T extends any[]> = T extends [arg: any, ...rest: infer U] ? U : T;
Enter fullscreen mode Exit fullscreen mode