Refer to microsoft/TypeScript#43516 for the definitive answer to this query.
Your usage involves labeled tuple elements; the a
, b
, and c
in your tuples act as labels for documentation purposes but do not impact assignability.
As per the TypeScript release notes, a key rule with labeled tuple elements is that either all elements of a tuple must be labeled, or none can bear labels. In the context of:
type B = [...A, c: boolean];
The initial spread of type A
within a variadic tuple is unlabeled, while the last element of type boolean
carries a label, rendering the type illegal.
According to microsoft/TypeScript#43516, you must provide a name for that initial rest element:
type B = [...args: A, c: boolean];
// --------> ^^^^^^ <----- assign a label here
// type B = [a: number, b: string, c: boolean]
Although slightly awkward because the labels from A
supersede the args
label from
B</code, it becomes necessary to supply something that will essentially be disregarded immediately.</p>
<p>However, according to <a href="https://github.com/microsoft/TypeScript/issues/39941" rel="nofollow noreferrer">microsoft/TypeScript#39941</a> (refer to <a href="https://github.com/microsoft/TypeScript/issues/39941#issuecomment-778868736" rel="nofollow noreferrer">this comment</a>) and discussions in <a href="https://github.com/microsoft/TypeScript/issues/43744" rel="nofollow noreferrer">microsoft/TypeScript#43744</a>, this rule exists because there are scenarios where the label is essential, and distinguishing them syntactically is apparently challenging.</p>
<p>For instance, if <code>A
were a standard array type, then you would have an output like
a tuple with a leading rest element, with the provided label pertaining to that rest element:
type AA = number[];
type BB = [...args: AA, c: boolean];
// type BB = [...args: number[], c: boolean]
There are suggestions in the linked issues about potentially relaxing the rule to accommodate cases similar to yours. However, this has not been integrated into the language thus far.
So there you have it. If you wish to add a label to one element in a tuple, consistency mandates assigning labels to all elements, including those spread from other tuple types.
Click here for a code demo on TypeScript playground