webNeat / just-types

A collection of handy Typescript types.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Tail type gives wrong results in specific recursive scenarios

TimonLukas opened this issue · comments

Hey there! Pretty cool library, thanks for sharing this. I could have recently needed this, it's good to know it exists! Though one tip, it would be helpful to add a link to the repository in your package.json, so the Github repository is linked on NPM :)

Anyways, here's the issue. There are some situations in which the Tail type will not work correctly, like this one (see on TS playground):

type Tail<List extends any[]> = List extends [infer _, ...infer Rest] ? Rest : []

type MatchEachLine<T extends string[]> =
  T extends [ head: string, ...tail: string[] ]
  ? MatchEachLine<Tail<T>>
  : never

This makes TS throw an error:

TS2344: Type 'Tail<T>' does not satisfy the constraint 'string[]'.
   Type 'unknown[] | []' is not assignable to type 'string[]'.
     Type 'unknown[]' is not assignable to type 'string[]'.
       Type 'unknown[]' is not assignable to type 'string[]'.
         Type 'unknown' is not assignable to type 'string'.

This should work, but TS somehow doesn't like this. Don't ask me why, hopefully it will be fixed in the future...

However, there is an alternative that fixes this and still fulfills all your existing tests (see on TS playground):

type Tail<List extends any[]> = ((...args: List) => any) extends (arg: any, ...rest: infer Rest) => any ? Rest : never

Hey @TimonLukas

Thank you for opening this issue and giving the solution, I am not sure why TS behave that way, I will try to dig deeper and understand where is this error coming from later. For now I applied your solution and released a new version.

Also thanks for the tip about the repository on package.json, I totally missed that 😅

Feel free to open other issues if you found other bugs.