Skip to content

Conversation

@som-sm
Copy link
Collaborator

@som-sm som-sm commented Nov 2, 2025

Fixes behaviour of ArraySlice with unions.

type Current = ArraySlice<[0, 1, 2, 3], 1, 2 | 3>;
//=> [1]

type Fixed = ArraySlice<[0, 1, 2, 3], 1, 2 | 3>;
//=> [1] | [2]
type Current1= ArraySlice<[0, 1, 2, 3], 2 | -3, 3>;
//=> []

type Updated = ArraySlice<[0, 1, 2, 3], 2 | -3, 3>;
//=> [2] | [1, 2]

This also fixes behaviour of StringSlice (Fixes #1289) with unions as it relies on ArraySlice, just needed the default type parameters to be fixed.

@som-sm som-sm force-pushed the fix/array-slice-with-unions branch from a7df7d4 to 376e418 Compare November 2, 2025 19:13
Repository owner deleted a comment from claude bot Nov 2, 2025
Repository owner deleted a comment from claude bot Nov 2, 2025
@som-sm som-sm force-pushed the fix/array-slice-with-unions branch from 376e418 to 8602b27 Compare November 3, 2025 07:47
@som-sm som-sm force-pushed the fix/array-slice-with-unions branch from 8602b27 to 223759d Compare November 3, 2025 08:29
Repository owner deleted a comment from claude bot Nov 3, 2025
Comment on lines +64 to +78
? IsNever<Start> extends true
? IsNever<End> extends true
? _ArraySlice<Array_, Start, End>
: End extends unknown // To distribute `End`
? _ArraySlice<Array_, Start, End>
: never // Never happens
: IsNever<End> extends true
? Start extends unknown // To distribute `Start`
? _ArraySlice<Array_, Start, End>
: never // Never happens
: Start extends unknown // To distribute `Start`
? End extends unknown // To distribute `End`
? _ArraySlice<Array_, Start, End>
: never // Never happens
: never // Never happens
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is complicated/verbose because the default value of Start/End is never, so we have to explicitly check for never before distributing, which introduces several branching cases.


I guess the reason for having the default value as never was that if End were simply Array_["length"], then union instantiations of End would give incorrect results.

For example,
ArraySlice<[0, 1, 2] | [0, 1], 0> would become
ArraySlice<[0, 1, 2] | [0, 1], 0, 3 | 2>,
which would then distribute to
ArraySlice<[0, 1, 2], 3 | 2> | ArraySlice<[0, 1], 3 | 2>,
and finally to
ArraySlice<[0, 1, 2], 3> | ArraySlice<[0, 1, 2], 2> | ArraySlice<[0, 1], 3> | ArraySlice<[0, 1], 2>,
which would be incorrect.

However, if we set the default for End to UnionMax<Array_["length"]>, that would fix this issue. The only thing is that explicitly passing never would no longer behave the same as omitting the argument. But that’s probably acceptable because never shouldn’t really be a valid value for Start/End anyway. In such cases, we can just return something like readonly unknown[] or [].

Copy link
Collaborator Author

@som-sm som-sm Nov 3, 2025

Choose a reason for hiding this comment

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

However, if we set the default for End to UnionMax<Array_["length"]>, that would fix this issue. The only thing is that explicitly passing never would no longer behave the same as omitting the argument. But that’s probably acceptable because never shouldn’t really be a valid value for Start/End anyway. In such cases, we can just return something like readonly unknown[] or [].

@sindresorhus If this is fine, then I'll open a separate PR for this.

Copy link
Owner

Choose a reason for hiding this comment

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

Yes, seems fine.

Repository owner deleted a comment from claude bot Nov 3, 2025
@som-sm som-sm marked this pull request as ready for review November 3, 2025 08:49
@sindresorhus sindresorhus merged commit 133258b into main Nov 3, 2025
13 checks passed
@sindresorhus sindresorhus deleted the fix/array-slice-with-unions branch November 3, 2025 11:03
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.

StringSlice is incorrect for union of string literals of different lengths

3 participants