Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ export type {IsUppercase} from './source/is-uppercase.d.ts';
export type {IsOptional} from './source/is-optional.d.ts';
export type {IsNullable} from './source/is-nullable.d.ts';
export type {TupleOf} from './source/tuple-of.d.ts';
export type {ArrayReverse} from './source/array-reverse.d.ts';

// Template literal types
export type {CamelCase, CamelCaseOptions} from './source/camel-case.d.ts';
Expand Down
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ Click the type names for complete docs.
- [`SplitOnRestElement`](source/split-on-rest-element.d.ts) - Splits an array into three parts, where the first contains all elements before the rest element, the second is the [`rest`](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) element itself, and the third contains all elements after the rest element.
- [`ExtractRestElement`](source/extract-rest-element.d.ts) - Extracts the [`rest`](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) element type from an array.
- [`ExcludeRestElement`](source/exclude-rest-element.d.ts) - Creates a tuple with the [`rest`](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) element removed.
- [`ArrayReverse`](source/array-reverse.d.ts) - Reverses the order of elements in a tuple type.

### Numeric

Expand Down
84 changes: 84 additions & 0 deletions source/array-reverse.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import type {If} from './if.d.ts';
import type {IsArrayReadonly} from './internal/array.d.ts';
import type {IfNotAnyOrNever, IsExactOptionalPropertyTypesEnabled} from './internal/type.d.ts';
import type {IsOptionalKeyOf} from './is-optional-key-of.d.ts';
import type {UnknownArray} from './unknown-array.d.ts';

/**
Reverses the order of elements in a tuple type.

@example
```ts
import type {ArrayReverse} from 'type-fest';

type A = ArrayReverse<[string, number, boolean]>;
//=> [boolean, number, string]

type B = ArrayReverse<readonly [string, number, ...boolean[]]>;
//=> readonly [...boolean[], number, string]

type C = ArrayReverse<['foo', 'bar'] | readonly [1, 2, 3]>;
//=> ["bar", "foo"] | readonly [3, 2, 1]

type D = ArrayReverse<string[]>;
//=> string[]

type E = ArrayReverse<[]>;
//=> []
```

Note: If the tuple contains optional elements, the result will be a union of tuples, refer to the examples below:

@example
```ts
import type {ArrayReverse} from 'type-fest';

type A = ArrayReverse<[string, number, boolean?]>;
//=> [boolean, number, string] | [number, string]

type B = ArrayReverse<[string, number?, boolean?]>;
//=> [boolean, number, string] | [number, string] | [string]

type C = ArrayReverse<[string?, number?, boolean?]>;
//=> [boolean, number, string] | [number, string] | [string] | []

type D = ArrayReverse<[string, number?, ...boolean[]]>;
//=> [...boolean[], number, string] | [string]

type E = ArrayReverse<[string?, number?, ...boolean[]]>;
//=> [...boolean[], number, string] | [string] | []
```

@category Array
*/
export type ArrayReverse<TArray extends UnknownArray> = IfNotAnyOrNever<TArray,
TArray extends unknown // For distributing `TArray`
? _ArrayReverse<TArray> extends infer Result
? If<IsArrayReadonly<TArray>, Readonly<Result>, Result>
: never // Should never happen
: never>; // Should never happen

type _ArrayReverse<
TArray extends UnknownArray,
BeforeRestAcc extends UnknownArray = [],
AfterRestAcc extends UnknownArray = [],
Result extends UnknownArray = never,
> =
keyof TArray & `${number}` extends never
// Enters this branch, if `TArray` is empty (e.g., `[]`),
// or `TArray` contains no non-rest elements preceding the rest element (e.g., `[...string[]]` or `[...string[], string]`).
? TArray extends readonly [...infer Rest, infer Last]
? _ArrayReverse<Rest, BeforeRestAcc, [...AfterRestAcc, Last], Result> // Accumulate elements that are present after the rest element in reverse order.
: Result | [...AfterRestAcc, ...TArray, ...BeforeRestAcc] // Add the rest element between the accumulated elements.
: TArray extends readonly [(infer First)?, ...infer Rest]
? IsOptionalKeyOf<TArray, '0'> extends true
? _ArrayReverse<
Rest,
[First | (If<IsExactOptionalPropertyTypesEnabled, never, undefined>), ...BeforeRestAcc], // Add `| undefined` for optional elements, if `exactOptionalPropertyTypes` is disabled.
AfterRestAcc,
Result | BeforeRestAcc
>
: _ArrayReverse<Rest, [First, ...BeforeRestAcc], AfterRestAcc, Result>
: never; // Should never happen, since `readonly [(infer First)?, ...infer Rest]` is a top-type for arrays.

export {};
Loading