[Typescript] 139. Extreme - Slice

Implement the JavaScript Array.slice function in the type system. Slice<Arr, Start, End> takes the three argument. The output should be a subarray of Arr from index Start to End. Indexes with negative numbers should be counted from reversely.

For example

type Arr = [1, 2, 3, 4, 5]
type Result = Slice<Arr, 2, 4> // expected to be [3, 4]

 

/* _____________ Your Code Here _____________ */

type SliceLeft<Arr extends readonly any[], Start, isNegStart, PrevArr extends readonly any[] = []> = 
  (isNegStart extends true ? Arr['length'] : PrevArr['length']) extends Start ? Arr
  : Arr extends [infer TFirst, ...infer TRest] ? SliceLeft<TRest, Start, isNegStart, [...PrevArr, TFirst]>
  : [];
type SliceLeftIgnoreSign<Arr extends readonly any[], Start extends number> = 
  `${Start}` extends `-${infer PosStart extends number}` ? SliceLeft<Arr, PosStart, true> : SliceLeft<Arr, Start, false>;


type SliceRight<Arr extends readonly any[], End extends number, isNegEnd, PrevArr extends readonly any[] = []> = 
  (isNegEnd extends true ? PrevArr['length'] : Arr['length']) extends End ? Arr
  : Arr extends [...infer TRest, infer TLast] ? SliceRight<TRest, End, isNegEnd, [TLast, ...PrevArr]>
  : [];
type SliceRightIgnoreSign<Arr extends readonly any[], End extends number> = 
  `${End}` extends `-${infer PosEnd extends number}` ? SliceRight<Arr, PosEnd, true> : SliceRight<Arr, End, false>;


type Slice<Arr extends readonly any[], Start extends number = 0, End extends number = Arr['length']> = 
  `${Start}` extends `-${string}` ? SliceRightIgnoreSign<SliceLeftIgnoreSign<Arr, Start>, End>
  : SliceLeftIgnoreSign<SliceRightIgnoreSign<Arr, End>, Start>


/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'

type Arr = [1, 2, 3, 4, 5]

type cases = [
  // basic
  Expect<Equal<Slice<Arr, 0, 1>, [1]>>,
  Expect<Equal<Slice<Arr, 0, 0>, []>>,
  Expect<Equal<Slice<Arr, 2, 4>, [3, 4]>>,

  // optional args
  Expect<Equal<Slice<[]>, []>>,
  Expect<Equal<Slice<Arr>, Arr>>,
  Expect<Equal<Slice<Arr, 0>, Arr>>,
  Expect<Equal<Slice<Arr, 2>, [3, 4, 5]>>,

  // negative index
  Expect<Equal<Slice<Arr, 0, -1>, [1, 2, 3, 4]>>,
  Expect<Equal<Slice<Arr, -3, -1>, [3, 4]>>,

  // invalid
  Expect<Equal<Slice<Arr, 10>, []>>,
  Expect<Equal<Slice<Arr, 1, 0>, []>>,
  Expect<Equal<Slice<Arr, 10, 20>, []>>,
]

 

posted @   Zhentiw  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2020-12-16 [Java Spring MVC] Paging and sorting DTOs
2020-12-16 [Java Spring MVC] @GetMapping, @PostMapping, @PutMapping, @PatchMapping & @DeleteMapping
2019-12-16 [Algorithm] 118. Pascal's Triangle
2019-12-16 [React] Create a Custom Suspending Image Component
2016-12-16 [RxJS] Flatten a higher order observable with concatAll in RxJS
2016-12-16 [RxJS] Flatten a higher order observable with mergeAll in RxJS
2016-12-16 [Compose] 8. A curated collection of Monoids and their uses
点击右上角即可分享
微信分享提示