Skip to content

Commit

Permalink
Fix MergeDeep in TypeScript 5.4
Browse files Browse the repository at this point in the history
After the change in microsoft/TypeScript#56004 the `PickRestType` was causing some types to be considered theoretically infinite in their recursion.

I can't wrap my mind around exactly why right now, but I can see how `PickRestType` on a crazy long tuple will cause a very deep recursion, so I decided to simply cap its recursion and return `unknown[]` if it goes past that point and that solved the errors.

Side effects:

- In practice: rarely any I believe
- In theory: some merged types will regress to `unknown[]` in TypeScript versions older than 5.4

Considerations:

Is the `DepthTracker extends Array<true> = []` + `PickRestTypeMaxDepth extends DepthTracker['length']` a good way to track depth? I know I have done a depth check previous times but can't remember what solution I picked then.

Fixes #784
  • Loading branch information
voxpelli committed Jan 29, 2024
1 parent eccf171 commit ee12b05
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions source/merge-deep.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ type MergeDeepRecord<
> = DoMergeDeepRecord<OmitIndexSignature<Destination>, OmitIndexSignature<Source>, Options>
& Merge<PickIndexSignature<Destination>, PickIndexSignature<Source>>;

/**
The maximal depth to use when looking for rest types in {@link PickRestType}
*/
type PickRestTypeMaxDepth = 50;

/**
Pick the rest type.
Expand All @@ -75,8 +80,12 @@ type Rest4 = PickRestType<[string, ...number[]]>; // => number[]
type Rest5 = PickRestType<string[]>; // => string[]
```
*/
type PickRestType<Type extends UnknownArrayOrTuple> = number extends Type['length']
? ArrayTail<Type> extends [] ? Type : PickRestType<ArrayTail<Type>>
type PickRestType<Type extends UnknownArrayOrTuple, DepthTracker extends Array<true> = []> = number extends Type['length']
? (
PickRestTypeMaxDepth extends DepthTracker['length']
? unknown[]
: ArrayTail<Type> extends [] ? Type : PickRestType<ArrayTail<Type>, [true, ...DepthTracker]>
)
: [];

/**
Expand Down

0 comments on commit ee12b05

Please sign in to comment.