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 @@ -178,6 +178,7 @@ export type {DelimiterCase} from './source/delimiter-case.d.ts';
export type {DelimiterCasedProperties} from './source/delimiter-cased-properties.d.ts';
export type {DelimiterCasedPropertiesDeep} from './source/delimiter-cased-properties-deep.d.ts';
export type {Join} from './source/join.d.ts';
export type {ArrayReverse} from './source/array-reverse.d.ts';
export type {Split, SplitOptions} from './source/split.d.ts';
export type {Words, WordsOptions} from './source/words.d.ts';
export type {Trim} from './source/trim.d.ts';
Expand Down
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ Click the type names for complete docs.
- [`Arrayable`](source/arrayable.d.ts) - Create a type that represents either the value or an array of the value.
- [`Includes`](source/includes.d.ts) - Returns a boolean for whether the given array includes the given item.
- [`Join`](source/join.d.ts) - Join an array of strings and/or numbers using the given string as a delimiter.
- [`ArrayReverse`](source/array-reverse.d.ts) - Reverses the order of elements in a tuple or array type.
- [`ArraySlice`](source/array-slice.d.ts) - Returns an array slice of a given range, just like `Array#slice()`.
- [`LastArrayElement`](source/last-array-element.d.ts) - Extracts the type of the last element of an array.
- [`FixedLengthArray`](source/fixed-length-array.d.ts) - Create a type that represents an array of the given type and length. The `Array` prototype methods that manipulate its length are excluded from the resulting type.
Expand Down
83 changes: 83 additions & 0 deletions source/array-reverse.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import type {IsExactOptionalPropertyTypesEnabled} from './internal/type.d.ts';
import type {IsOptionalKeyOf} from './is-optional-key-of.d.ts';
import type {IsArrayReadonly} from './internal/array.d.ts';
import type {UnknownArray} from './unknown-array.d.ts';
import type {IsAny} from './is-any.d.ts';
import type {If} from './if.d.ts';

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

@example
```
type T1 = ArrayReverse<['a', 'b', 'c']>
//=> ['c', 'b', 'a']

type T2 = ArrayReverse<readonly [1, 2, 3, 4, ...string[]]>
//=> readonly [...string[], 4, 3, 2, 1]

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

type T4 = ArrayReverse<readonly [1, 2, ...number[], 4]>
//=> readonly [4, ...number[], 2, 1]

declare function Arrayreverse<const T extends unknown[]>(array: T): ArrayReverse<T>;
Arrayreverse(['a', 'b', 'c', 'd']);
//=> ['d', 'c', 'b', 'a']
```

Note: If the array contains optional elements, the result will be a union of tuples covering all possible cases.

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

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

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

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

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

@category Array
*/
export type ArrayReverse<Array_ extends UnknownArray> =
IsAny<Array_> extends true ? Array_ // Prevent the return of `Readonly<[] | [unknown] | unknown[] | [...unknown[], unknown]>`
: Array_ extends UnknownArray // For distributing `Array_`
? _ArrayReverse<Array_> extends infer Result
? If<IsArrayReadonly<Array_>, Readonly<Result>, Result> // Preserve readonly modifier
: never // Should never happen
: never; // Should never happen

/**
Core type for {@link ArrayReverse `ArrayReverse`}
*/
type _ArrayReverse<
Array_ extends UnknownArray,
HeadAcc extends UnknownArray = [],
TailAcc extends UnknownArray = [],
> =
keyof Array_ & `${number}` extends never // Is `Array_` leading a rest element or empty
? Array_ extends readonly [...infer Rest, infer Last]
? _ArrayReverse<Rest, [...HeadAcc, Last], TailAcc> // Accumulate elements after a rest element in Arrayreverse order
: [...HeadAcc, ...Array_, ...TailAcc] // Add the rest element between the accumulated elements.
: Array_ extends readonly [(infer First)?, ...infer Rest]
// Accumulate elements before a rest element in Arrayreverse order.
? IsOptionalKeyOf<Array_, 0> extends true
? (
| TailAcc // Union all possible cases when optional elements exist.
| _ArrayReverse<Rest, HeadAcc, [
If<IsExactOptionalPropertyTypesEnabled, First, First | undefined>, // Add `| undefined` for optional elements, if `exactOptionalPropertyTypes` is disabled.
...TailAcc,
]>
) : _ArrayReverse<Rest, HeadAcc, [First, ...TailAcc]>
: never; // Should never happen

export {};
Loading