question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow inferring rest element types in conditional types involving tuples

See original GitHub issue

Search Terms

rest element infer tuple

Suggestion

Currently, inferring single elements of tuple types is possible using the infer keyword:

type FirstArg<T extends any[]> = 
	T extends [infer R, ...any[]] ? R : 
	T extends [] ? undefined : 
	never;
type T1 = FirstArg<[number, 2, 3]>; // number
type T2 = FirstArg<[1, 2, 3]>; // 1
type T3 = FirstArg<["", 2]>; // ""
type T4 = FirstArg<[]>; // undefined

However it is not possible to infer the type of the remaining arguments in one go, except by resorting to functions:

type RestArgs<T extends any[]> = 
	T extends [any, infer R[]] ? R : // this does not work - no way to specify that R should be an array!
	T extends [any] ? []] : 
	never;

// this does
type RestArgs<T extends any[]> =
	((...args: T) => void) extends ((first: any, ...rest: infer S1) => void) ? S1
	: T extends [infer S2] ? []
	: T extends [] ? []
	: never;
type T1 = RestArgs<[1,2,3]>; // [2, 3]
type T2 = RestArgs<[1,2]>; // [2]
type T3 = RestArgs<[1]>; // []
type T4 = RestArgs<[]>; // []

I would like to see the possibility to infer rest types in tuples, e.g. like this (square brackets):

type RestArgs<T extends any[]> = T extends [any, infer R[]] ? R : never;

or like this (3 dots)

type RestArgs<T extends any[]> = T extends [any, infer ...R] ? R : never;

Checklist

My suggestion meets these guidelines:

  • This wouldn’t be a breaking change in existing TypeScript / JavaScript code
  • This wouldn’t change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn’t a runtime feature (e.g. new expression-level syntax)

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:26
  • Comments:5

github_iconTop GitHub Comments

9reactions
chocolateboycommented, Nov 14, 2020

This works in TypeScript v4 (via variadic tuple types):

type Tail<T extends any[]> = T extends [any, ...infer U] ? U : never;

5reactions
jscheinycommented, Jul 25, 2018

I just ran into this issue myself and wanted to throw in my two cents about the syntax for how this would behave. Considering how this inference is written for function types and how rest elements of tuples are constructed:

type Tail<T> = T extends (head: any, ...tail: infer U) ? U : never;

type Rest = string[];
type Tuple = [any, ...Rest];

I would suggest the following syntax:

type Tail<T> = T extends [any, ...infer U] ? U : never;
Read more comments on GitHub >

github_iconTop Results From Across the Web

Playground Example - Rest Elements in Tuple Types - TypeScript
// Tuples allow TypeScript to describe arrays like: [string, number] - which means that only a string and a number can be used...
Read more >
infer generic parameters in rest tuple type - Stack Overflow
Mapped types preserve tuple while allowing you to map every element type of a tuple to a new element type in the resulting...
Read more >
Conditional types in TypeScript - Artsy Engineering
Let's add basic types to this function so we can let TypeScript worry about whether we are using it safely or not.
Read more >
Using tuples - Learn TypeScript
A tuple can be thought of as an array with a fixed number of elements. Some of the hooks in ... Typescript can't...
Read more >
Tuples in rest parameters and spread expressions - 书栈网
When tuple types are inferred for rest parameters, optional parameters in the source become optional tuple elements in the inferred type. The ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found