awesome-typescript icon indicating copy to clipboard operation
awesome-typescript copied to clipboard

「重学TS 2.0 」TS 练习题第二十七题

Open semlinker opened this issue 4 years ago • 14 comments

实现一个 Reverse 工具类型,用于对元组类型中元素的位置颠倒,并返回该数组。元组的第一个元素会变成最后一个,最后一个元素变成第一个。

type Reverse<
  T extends Array<any>,
  R extends Array<any> = []
> = // 你的实现代码

type R0 = Reverse<[]> // []
type R1 = Reverse<[1, 2, 3]> // [3, 2, 1]

请在下面评论你的答案。

semlinker avatar Sep 20 '21 12:09 semlinker

type Reverse<
  T extends Array<any>,
  R extends Array<any> = []
> = T extends [infer A,... infer B]? Reverse<B,[A,...R]> : R 

type R0 = Reverse<[]> // []
type R1 = Reverse<[1, 2, 3]> // [3, 2, 1]

suica avatar Sep 20 '21 16:09 suica

type Reverse<
  T extends Array<any>
> = T extends [infer First, ...infer Rest] ? [...Reverse<Rest>, First] : []

type R0 = Reverse<[]> // []
type R1 = Reverse<[1, 2, 3]> // [3, 2, 1]

zerolee1231 avatar Sep 20 '21 17:09 zerolee1231

type Reverse<T extends Array<any>> = T extends [infer First, ...infer Rest]
  ? [...Reverse<Rest>, First]
  : [];

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

zhaoxiongfei avatar Sep 20 '21 17:09 zhaoxiongfei

type Push<T extends any[], V> =  [...T, V];

type Reverse<
  T extends Array<any>,
  R extends Array<any> = []
> = T extends [infer A, ...infer K] ? K extends [] ? Push<R, A> : Push<Reverse<K, R>, A> : []

type R0 = Reverse<[]> // []
type R1 = Reverse<[1, 2, 3]> // [3, 2, 1]

douhao1988 avatar Sep 21 '21 12:09 douhao1988

向下递归时,变换一下两个 infer 变量的位置即可

type Reverse<T extends any[]> = T extends [infer R1, ...infer R2] ? [...Reverse<R2>, R1] : []

type R0 = Reverse<[]> // []
type R1 = Reverse<[1, 2, 3]> // [3, 2, 1]

xiaoYuanDun avatar Sep 23 '21 10:09 xiaoYuanDun

type Reverse<
  T extends Array<any>,
  R extends Array<any> = []
> = T extends [infer F, ...infer B] ? Reverse<B, [F, ...R]> : R// Reverse<B, [F, ...R]>就将前面的类型放置于后面

type R0 = Reverse<[]> // []
type R1 = Reverse<[1,2,3]> // [3,2,1]

mingzhans avatar Sep 26 '21 14:09 mingzhans

题解

这里采用递归方式,每次递归都把第一项 First 放在最后,并把递归结果展开:

type Reverse<T extends Array<any>> = 
  T extends [infer First, ...infer Rest]
  ? [...Reverse<Rest>, First]
  : [];

type R0 = Reverse<[]> // []
type R1 = Reverse<[1, 2, 3]> // [3, 2, 1]
type R2 = Reverse<[1, 2, 3, 4, 5]> //  [5, 4, 3, 2, 1]

拓展

本题还可以引入一个空数组暂存结果:

type Reverse<
  T extends Array<any>,
  A extends Array<any> = []
> = T extends [infer First, ...infer Rest] ?  Reverse<Rest, [First, ...A]> : A;

第一次执行的时候,把 T 分成第一项 First 和剩余的 Rest,每次递归的时候,把 First 和暂存数组 A 合并,作为递归的第二个参数,即上一步翻转的结果,到最后返回暂存数组 A 即可。

类似的还可以这么处理:

type Reverse<
  T extends Array<any>,
  A extends Array<any> = []
> = T extends [...infer Rest, infer Last] ?  
    A['length'] extends T['length'] ? A :
    Reverse<Rest, [...A, Last]> : A;

type R0 = Reverse<[]> // []
type R1 = Reverse<[1, 2, 3]> // [3, 2, 1]
type R2 = Reverse<[1, 2, 3, 4, 5]> //  [5, 4, 3, 2, 1]

pingan8787 avatar Sep 27 '21 15:09 pingan8787

type Reverse<
T extends Array<any>,
R extends Array<any> = []
> = T extends [infer A, ...infer B]
  ? [...Reverse<B>, A]
  : [];

type R0 = Reverse<[]> // []
type R1 = Reverse<[1, 2, 3]> // [3, 2, 1]

这类型的问题,着眼点都在数组的形状上。

zhaoxiongfei avatar Oct 02 '21 09:10 zhaoxiongfei

type Reverse<T extends Array<any>, R extends Array<any> = []> = T extends [...infer A, infer B] ? [B, ...Reverse<A>] : [];

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

Gengar-666 avatar Nov 01 '21 08:11 Gengar-666


type Reverser<
  T extends Array<any>,
  R extends Array<any> = []
> = T extends [infer F, ...infer Rest]
    ? Reverser<Rest, [F,...R]>
    : R

type R0 = Reverser<[]>
type R1 = Reverser<[1,2,3,4,5]>

ShawDuChen avatar Dec 29 '21 06:12 ShawDuChen

type R0 = Reverse<[]> // []
type R1 = Reverse<[1, 2, 3, 4, 5]> // [3, 2, 1]

type Reverse<
  T extends Array<any>,
  R extends Array<any> = []
> =
  T extends [infer First, ...infer Rest]
    ? Reverse<Rest, [First, ...R]>
    : R

waleiwalei avatar Mar 16 '22 05:03 waleiwalei

  type Reverse<
    T extends Array<any>,
    R extends Array<any> = []
  > = T extends [infer First, ...infer Rest] ? Reverse<Rest, [First, ...R]> : R

hezhisheng1930 avatar Aug 12 '22 07:08 hezhisheng1930

type Reverse<
  T extends Array<any>,
  R extends Array<any> = []
> = T extends [] ? R : (
  T extends [infer First, ...infer Rest] ? Reverse<Rest, [First, ...R]> : R
)

zhixiaotong avatar Feb 03 '23 03:02 zhixiaotong

type Reverse<
  T extends Array<any>,
  R extends any[] = [],
> = T extends [infer A, ...infer Rest]
  ? Reverse<[...Rest], [A, ...R]>
  : R

SweeperDuan avatar Dec 12 '23 07:12 SweeperDuan