microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.21k stars 12.51k forks source link

Expressive Reversed type for tuples #60575

Closed redpulp closed 8 hours ago

redpulp commented 9 hours ago

⚙ Compilation target

ES2024

⚙ Library

5.6.3

Missing / Incorrect Definition

interface Array<T> {
    reverse: T[];
}

This loses all information of the order of reversed tuples, I usually have to use the following code to override the behaviour of Array.prototype.reverse

type ReversedTuple<T extends any[], R extends any[] = []> = ReturnType<T extends [infer F, ...infer L] ? () => Reverse<L, [F, ...R]> : () => R>;
type ReversedTupleOrArray<T> = T extends [any, ...any[]] ? Reverse<T> : T;

Sample Code

const myTuple: [number, string, string] = [1, 'hello', 'world']
const reversedTuple = myTuple.reverse() // (string | number)[]
MartinJohns commented 8 hours ago

Related: https://github.com/microsoft/TypeScript/issues/13360#issuecomment-271365952

And in general reverse() is troublesome for tuples, because it modifies the array in-place.

redpulp commented 8 hours ago

And in general reverse() is troublesome for tuples, because it modifies the array in-place.

Yeah tuples should be immutable by definition, so I get how this would be troublesome here. I only know of dirty tricks to avoid this (like [...array].reverse()) so I understand the issue, thanks for the comment