|
| 1 | +# Step 2: Reverse |
| 2 | + |
| 3 | +Next up, let's have you start writing your own conditional types from scratch. |
| 4 | +You'll be working with `...` spread and rest operations, which conditional types are able to use on types known to be array types. |
| 5 | +You can enforce that a type parameter is an array type by giving it an array constraint like `extends any[]`. |
| 6 | + |
| 7 | +This `ArrayLength` type ensures `T` is some kind of array, so `T` is guaranteed to have a `length` property: |
| 8 | + |
| 9 | +```ts |
| 10 | +type ArrayLength<T extends any[]> = T["length"]; |
| 11 | + |
| 12 | +// Type: number |
| 13 | +type LengthOfStringArray = ArrayLength<string[]>; |
| 14 | + |
| 15 | +// Type: 3 |
| 16 | +type LengthOfTupleTrio = ArrayLength<["a", "b", "c"]>; |
| 17 | +``` |
| 18 | + |
| 19 | +Spreads on array types allow types to _combine_ array types. |
| 20 | +For example, this `Unshift` type adds an item `Item` to the beginning of the `Rest` array: |
| 21 | + |
| 22 | +```ts |
| 23 | +type Unshift<Rest extends any[], Item> = [Item, ...Rest]; |
| 24 | + |
| 25 | +// Type: ["First!", "a", "b", "c"] |
| 26 | +type PrefixFirst = Unshift<["a", "b", "c"], "First!">; |
| 27 | +``` |
| 28 | + |
| 29 | +Rests on array types allow types to _extract_ from array types. |
| 30 | +For example, this `Pop` type ignores the first element in the array type retrieves the rest as `Rest`: |
| 31 | + |
| 32 | +```ts |
| 33 | +type Pop<T extends any[]> = T extends [any, ...infer Rest] ? Rest : never; |
| 34 | + |
| 35 | +// Type: ["b", "c"] |
| 36 | +type PopFirst = Pop<["a", "b", "c"]>; |
| 37 | +``` |
| 38 | + |
| 39 | +Your task for this step is to use both concepts to create a recursive `Reverse` type. |
| 40 | +`Reverse` should take in an array as a type parameter `T` and return an array that consists of: |
| 41 | + |
| 42 | +1. The first element in `T` |
| 43 | +2. ...a rest of the result of `Reverse` on the remaining elements of `T` |
| 44 | + |
| 45 | +> Fans of functional programming may recognize this as a very functional way of reversing a list! |
| 46 | +
|
| 47 | +## Specification |
| 48 | + |
| 49 | +Write a `Reverse` type that takes in one type parameter that must be an array: `T`. |
| 50 | + |
| 51 | +It should result in a reversed array or tuple type of `T`'s elements. |
| 52 | + |
| 53 | +## Examples |
| 54 | + |
| 55 | +- `Reverse<number[]>` -> `number[]` |
| 56 | +- `Reverse<(number | string)[]>` -> `(number | string)[]` (which may also be written as `(string | number)[]`) |
| 57 | +- `Reverse<['a', 'b', 'c']>` -> `['c', 'b', 'a']` |
| 58 | + |
| 59 | +## Files |
| 60 | + |
| 61 | +- `index.ts`: Write your `Reverse` type here |
| 62 | +- `solution.ts`: Solution code |
0 commit comments