Created
August 15, 2018 12:53
-
-
Save willfrew/6c6de7225c0cbec4545631efa4478193 to your computer and use it in GitHub Desktop.
Fun with tuple types in Typescript 3.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Head<T extends unknown[]> = T[0]; | |
type FnWithArgs<T extends unknown[]> = (...args: T) => void; | |
type TailArgs<T> = T extends (x: unknown, ...args: infer T) => unknown ? T : never; | |
type Tail<T extends unknown[]> = TailArgs<FnWithArgs<T>>; | |
// Lol | |
type Decr<T extends number> = | |
T extends 10 ? 9 : | |
T extends 9 ? 8 : | |
T extends 8 ? 7 : | |
T extends 7 ? 6 : | |
T extends 6 ? 5 : | |
T extends 5 ? 4 : | |
T extends 4 ? 3 : | |
T extends 2 ? 1 : | |
T extends 1 ? 0 : | |
never; | |
type Length<T extends unknown[]> = T['length']; | |
type Last<T extends unknown[]> = T[Decr<Length<T>>]; | |
type Tuple = [number, string, boolean, string, { a: number }]; | |
type LengthT = Length<Tuple>; // 5 | |
type LastT = Last<Tuple>; // { a: number } | |
type HeadT = Head<Tuple>; // string | |
type TailT = Tail<Tuple>; // [string, boolean, string, { a: number }] |
With TypeScript 4.0 variadic tuple types, Tail can be simplified as:
type Tail<T extends unknown[]> = T extends [unknown, ...infer TailType] ? TailType : never;
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Cool, thx for sharing. A couple of issues:
TailArgs
should not reuseT
, it does not work as it is.// number