Как написать `Invert` типа в машинописи, чтобы инвертировать порядок кортежей - PullRequest
0 голосов
/ 09 января 2020
type a = [1,2,3]
type Invert<T extends any[] & {'0': any}> = ???
type b = Invert<a> // should yield [3,2,1]

Я застрял, чтобы выяснить определение типа Invert кортежа, также типа Init и Last, хотя они могут быть сконструированы друг из друга

что я попытался:

  1. позиционировать тип в определении параметра функции и вывести часть Rest, этот подход получил только часть Tail с параметрами остальных

1 Ответ

2 голосов
/ 09 января 2020

Это работает, только если вы знаете длину массива:

type a = [1,2,3]
type Invert<T extends [any, any, any]> = [T[2], T[1], T[0]];
type b = Invert<a> // should yield [3,2,1]

Обновление

На самом деле существует решение (найдено здесь при выпуске проекта машинописного текста):

export type Prepend<Tuple extends any[], Addend> = 
     ((_: Addend, ..._1: Tuple) => any) extends ((..._: infer Result) => any) ? Result : never;

export type Reverse<Tuple extends any[], Prefix extends any[] = []> = {
    0: Prefix;
    1: ((..._: Tuple) => any) extends ((_: infer First, ..._1: infer Next) => any)
        ? Reverse<Next, Prepend<Prefix, First>>
        : never;
}[Tuple extends [any, ...any[]] ? 1 : 0];


type b = Reverse<[1, 2, 3]>; // type b = [3, 2, 1]

Playground Link

...