-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
157 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"type-plus": minor | ||
--- | ||
|
||
Support `Delete` and `Insert` for `SplitAt`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,74 @@ | ||
import type { NeverType } from '../never/never_type.js' | ||
import type { IsTuple } from '../tuple/tuple_type.js' | ||
import type { IndexAt } from './array_index.js' | ||
import type { ArrayType } from './array_type.js' | ||
|
||
/** | ||
* Splits an array into two at the specified `Index`. | ||
* ⚗️ *transform* | ||
* | ||
* Splits array or tuple `A` into two at the specified `Index`. | ||
* | ||
* If the `Index` is out of bounds, | ||
* it will set to the boundary value, similar to `array.splice()`. | ||
* it will set to the boundary value. | ||
* | ||
* It is the type level `splice()`. | ||
* | ||
* @example | ||
* ```ts | ||
* SplitAt<[1, 2, 3, 4, 5], 0> // [[], [1, 2, 3, 4, 5]] | ||
* SplitAt<[1, 2, 3, 4, 5], -5> // [[], [1, 2, 3, 4, 5]] | ||
* | ||
* SplitAt<[1, 2, 3, 4, 5], 2> // [[1, 2], [3, 4, 5]] | ||
* SplitAt<[1, 2, 3, 4, 5], -3> // [[1, 2], [3, 4, 5]] | ||
* | ||
* SplitAt<[1, 2, 3, 4, 5], 4> // [[1, 2, 3, 4], [5]] | ||
* SplitAt<[1, 2, 3, 4, 5], -1> // [[1, 2, 3, 4], [5]] | ||
* SplitAt<[1, 2, 3, 4, 5], 2, 2> // [[1, 2, 5], [3, 4]] | ||
* | ||
* SplitAt<[1, 2, 3, 4, 5], 5> // [[1, 2, 3, 4, 5], []] | ||
* SplitAt<[1, 2, 3, 4, 5], 2, 2, ['a', 'b']> // [[1, 2, 'a', 'b', 5], [3, 4]] | ||
* | ||
* // out of bound resets to boundary | ||
* SplitAt<[1, 2, 3, 4, 5], 6> // [[1, 2, 3, 4, 5], []] | ||
* SplitAt<[1, 2, 3, 4, 5], -6> // [[], [1, 2, 3, 4, 5]] | ||
* ``` | ||
*/ | ||
export type SplitAt<A extends unknown[], Index extends number> = ArrayType< | ||
export type SplitAt< | ||
A extends unknown[], | ||
Index extends number, | ||
DeleteCount extends number | never = never, | ||
Insert extends unknown[] | never = never | ||
> = ArrayType< | ||
A, | ||
[A, A], | ||
ArraySplitAtDevice<A, [], IndexAt<A, Index>> | ||
SplitAt._<A, [], [], IndexAt._<A, Index>, DeleteCount, Insert> | ||
> | ||
|
||
/** | ||
* Splits an array into two at the specified `Index`. | ||
* The device does not work on negative index nor out of bound index. | ||
*/ | ||
export type ArraySplitAtDevice< | ||
A extends unknown[], | ||
B extends unknown[], | ||
Index extends number | ||
> = Index extends B['length'] | ||
? [B, A] | ||
: A extends [infer Head, ...infer Tail] | ||
? ArraySplitAtDevice<Tail, [...B, Head], Index> | ||
: never | ||
export namespace SplitAt { | ||
export type _< | ||
A extends unknown[], | ||
B extends unknown[], | ||
C extends unknown[], | ||
Index extends number, | ||
DeleteCount, | ||
Insert extends unknown[], | ||
> = 0 extends A['length'] | ||
? IsTuple<Insert, [[...Insert, ...B], C], [B, C]> | ||
: (Index extends B['length'] | ||
? _D<A, B, C, DeleteCount, Insert> | ||
: (A extends [infer Head, ...infer Tail] | ||
? _<Tail, [...B, Head], [], Index, DeleteCount, Insert> | ||
: 'unexpected: A does not extends [Head, ...Tail]')) | ||
|
||
export type _D< | ||
A extends unknown[], | ||
B extends unknown[], | ||
C extends unknown[], | ||
DeleteCount, | ||
Insert extends unknown[], | ||
> = NeverType< | ||
DeleteCount, | ||
[B, A], | ||
DeleteCount extends C['length'] | ||
? IsTuple<Insert, [[...B, ...Insert, ...A], C], [[...B, ...A], C]> | ||
: (A extends [infer Head, ...infer Tail] | ||
? _D<Tail, B, [...C, Head], DeleteCount, Insert> | ||
: IsTuple<Insert, [[...Insert, ...B], C], [B, C]> | ||
) | ||
> | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters