Skip to content

ExcludeRestElement: Fix generic assignability with arrays#1274

Merged
sindresorhus merged 4 commits intomainfrom
fix/exclude-rest-element-generic-compatibility
Oct 25, 2025
Merged

ExcludeRestElement: Fix generic assignability with arrays#1274
sindresorhus merged 4 commits intomainfrom
fix/exclude-rest-element-generic-compatibility

Conversation

@som-sm
Copy link
Collaborator

@som-sm som-sm commented Oct 17, 2025

Currently, instantiations of ExcludeRestElement with generic types are not assignable to readonly unknown[], this PR fixes this issue.

This issue is also related to #1166 (comment). In general, it's better to handle any and never cases explicitly.

@som-sm som-sm requested a review from sindresorhus October 17, 2025 15:24
@som-sm som-sm marked this pull request as draft October 17, 2025 15:26
@som-sm som-sm force-pushed the fix/exclude-rest-element-generic-compatibility branch from ad12bdd to dc490d4 Compare October 17, 2025 15:32
: [...Result[0], ...Result[2]]
: Result
: never;
: never
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is Result (and not never), then the compiler thinks the type produces something more than just arrays.

@claude

This comment was marked as outdated.

@som-sm som-sm force-pushed the fix/exclude-rest-element-generic-compatibility branch from ffaeaf4 to dc490d4 Compare October 17, 2025 15:37
@claude

This comment was marked as outdated.

@claude

This comment was marked as spam.

@som-sm som-sm marked this pull request as ready for review October 17, 2025 15:41
Repository owner deleted a comment from claude bot Oct 17, 2025
Comment on lines +30 to +38
export type ExcludeRestElement<Array_ extends UnknownArray> = IfNotAnyOrNever<Array_,
SplitOnRestElement<Array_> extends infer Result
? Result extends readonly UnknownArray[]
? IsArrayReadonly<Array_> extends true
? Readonly<[...Result[0], ...Result[2]]>
: [...Result[0], ...Result[2]]
: Result
: never;
: never
: never
>;
Copy link
Contributor

@benzaria benzaria Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please consider using IsAnyOrNever instead, as it provides more reliable handling for recursive types.
Refer my #1192 comment, and your #1266 comment regarding If* types.

Suggested change
export type ExcludeRestElement<Array_ extends UnknownArray> = IfNotAnyOrNever<Array_,
SplitOnRestElement<Array_> extends infer Result
? Result extends readonly UnknownArray[]
? IsArrayReadonly<Array_> extends true
? Readonly<[...Result[0], ...Result[2]]>
: [...Result[0], ...Result[2]]
: Result
: never;
: never
: never
>;
export type ExcludeRestElement<Array_ extends UnknownArray> =
IsAnyOrNever<Array_> extends true ? Array_
: SplitOnRestElement<Array_> extends infer Result
? Result extends readonly UnknownArray[]
? IsArrayReadonly<Array_> extends true
? Readonly<[...Result[0], ...Result[2]]>
: [...Result[0], ...Result[2]]
: never
: never;

Copy link
Collaborator Author

@som-sm som-sm Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IfNotAnyOrNever works perfectly fine in this case because ExcludeRestElement is not a recursive type. Added test cases for long tuples in #0aed831.


your #1266 comment regarding If* types.

This was only for recursive types.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, if used properly, IfNotAnyOrNever can even be used with recursive types without any problems. Added a note in #1276.

Repository owner deleted a comment from claude bot Oct 17, 2025
Repository owner deleted a comment from claude bot Oct 17, 2025
@sindresorhus sindresorhus merged commit 12ef5b2 into main Oct 25, 2025
7 checks passed
@sindresorhus sindresorhus deleted the fix/exclude-rest-element-generic-compatibility branch October 25, 2025 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants