type-plus
Version:
Provides additional types for TypeScript.
283 lines (182 loc) • 7.35 kB
Markdown
# Tuple
In TypeScript, the type of an JavaScript array can be an [array](../array/readme.md) or a [tuple](#tuple).
A *tuple type* is an array with fixed number of entries.
Each entry in the *tuple* is specified explicitly.
## Type Checking
The `TupleType<T>` and friends are used to check if `T` is a tuple, excluding array.
### [TupleType](./tuple_type.ts#l21)
`TupleType<T, Then = T, Else = never, Cases = { never }>`
🌪️ *filter*
Filter `T` to ensure it is a tuple, excluding array.
```ts
import type { TupleType } from 'type-plus'
type R = TupleType<[]> // []
type R = TupleType<[1]> // [1]
type R = TupleType<number[]> // never
type R = TupleType<string> // never
type R = TupleType<never> // never
type R = TupleType<unknown> // never
```
Overridable cases:
- `never`: if `T` is `never`, it returns `Else`.
### [IsTuple](./array_type.ts#l47)
`IsTuple<T, Then = true, Else = false, Cases = { never }>`
🎭 *validate*
Validate that `T` is a tuple, excluding array.
```ts
import type { IsTuple } from 'type-plus'
type R = IsTuple<[]> // true
type R = IsTuple<number[]> // false
type R = IsTuple<string> // false
type R = IsTuple<never> // false
type R = IsTuple<unknown> // false
```
Overridable cases:
- `never`: if `T` is `never`, it returns `Else`.
### [NotTupleType](./tuple_type.ts#l70)
`NotArrayType<T, Then = T, Else = never, Cases = { never }>`
🌪️ *filter*
Filter `T` to ensure it is not an tuple, excluding array.
```ts
import type { NotArrayType } from 'type-plus'
type R = NotTupleType<[]> // never
type R = NotTupleType<[1]> // never
type R = NotTupleType<number[]> // number[]
type R = NotTupleType<string> // string
type R = NotTupleType<never> // never
type R = NotTupleType<unknown> // unknown
```
Overridable cases:
- `never`: if `T` is `never`, it returns `Else`.
### [IsNotTupleType](./tuple_type.ts#l92)
`IsNotTupleType<T, Then = true, Else = false, Cases = { never }>`
🎭 *validate*
Validate that `T` is not a tuple, excluding array.
```ts
import type { IsNotTupleType } from 'type-plus'
type R = IsNotTuple<[]> // false
type R = IsNotTuple<[1]> // false
type R = IsNotTuple<number[]> // true
type R = IsNotTuple<string> // true
type R = IsNotTuple<never> // true
type R = IsNotTuple<unknown> // true
```
Overridable cases:
- `never`: if `T` is `never`, it returns `Else`.
## [CommonPropKeys](./common_prop_keys.ts#l22)
`CommonPropKeys<T extends Record[], Options = { caseNever }>`
⚗️ *transform*
🔢 *customizable*
Gets the common property keys of the elements in tuple or array `T`.
```ts
import { CommonPropKeys } from 'type-plus'
type R = CommonPropKeys<[{ a: 1, c: 1 }, { b: 1, c: 2 }]> // 'c'
type R = CommonPropKeys<[{ a: 1 }, { b: 1 }]> // never
type R = CommonPropKeys<Array<{ a: 1, b: 1 } | { a: 1, c: 1 }>> // 'a'
type R = CommonPropKeys<[{ a: 1 }, { b: 1 }]> // never
type R = CommonPropKeys<never> // caseNever: never
// customization
type R = CommonPropKeys<never, { caseNever: 1 }> // 1
```
## [DropFirst](./drop.ts#l26)
`DropFirst<T extends unknown[], Options = { caseArray, caseEmptyTuple }>`
⚗️ *transform*
🔢 *customizable*
Drops the first entry in the tuple `T`.
```ts
import { DropFirst } from 'type-plus'
type R = DropFirst<[1, 2, 3]> // [2, 3]
type R = DropFirst<[string]> // []
type R = DropFirst<string[]> // caseArray: string[]
type R = DropFirst<[]> // caseEmptyTuple: []
// customization
type R = DropFirst<string[], { caseArray: 1 }> // 1
type R = DropFirst<[], { caseEmptyTuple: 1 }> // 1
```
## [DropLast](./drop.ts#l72)
`DropLast<T extends unknown[], Options = { array, empty_tuple }>`
⚗️ *transform*
🔢 *customizable*
Drops the last entry in the tuple `T`.
```ts
import { DropLast } from 'type-plus'
type R = DropLast<[1, 2, 3]> // [2, 3]
type R = DropLast<[string]> // []
type R = DropLast<string[]> // caseArray: string[]
type R = DropLast<[]> // caseEmptyTuple: []
// customization
type R = DropLast<string[], { caseArray: 1 }> // 1
type R = DropLast<[], { caseEmptyTuple: 1 }> // 1
```
## [DropMatch](./drop.ts)
`DropMatch<A extends Readonly<Array<unknown>>, Criteria>`
⚗️ *transform*
Drops entries matching `Criteria` in array or tuple `A`.
```ts
type R = DropMatch<Array<string | undefined>, undefined> // string[]
type R = DropMatch<Array<string>, string> // never[]
type R = DropMatch<Array<1 | 2>, number> // never[]
```
## [TuplePlus](./tuple_plus.ts)
`TuplePlus` contains type utilities specific for *tuple*.
The input type are not checked and assumed to be *tuple*.
## [TuplePlus.CommonPropKeys](./tuple_plus.common_prop_keys.ts#l22)
`TuplePlus.CommonPropKeys<T extends Record[], Options = { caseNever }>`
⚗️ *transform*
🔢 *customizable*
Gets the common property keys of the elements in tuple `T`.
```ts
import { type TuplePlus } from 'type-plus'
type R = TuplePlus.CommonPropKeys<[{ a: 1, c: 1 }, { b: 1, c: 2 }]> // 'c'
type R = TuplePlus.CommonPropKeys<[{ a: 1 }, { b: 1 }]> // never
type R = TuplePlus.CommonPropKeys<Array<{ a: 1, b: 1 } | { a: 1, c: 1 }>> // 'a'
type R = TuplePlus.CommonPropKeys<[{ a: 1 }, { b: 1 }]> // never
type R = TuplePlus.CommonPropKeys<never> // caseNever: never
// customization
type R = TuplePlus.CommonPropKeys<never, { caseNever: 1 }> // 1
```
### [TuplePlus.Filter](./tuple_plus.filter.ts)
`TuplePlus.Filter<T, Criteria>`
⚗️ *transform*
Filter entries matching `Criteria` in tuple `T`.
```ts
import { TuplePlus } from 'type-plus'
type R = TuplePlus.Filter<[1, 2, '3'], number> // [1, 2]
```
### [`TuplePlus.Find`](./tuple_plus.find.ts#l51)
`TuplePlus.Find<A, Criteria, Options { widen, caseArray, caseEmptyTuple, caseNever, caseNotMatch, caseWiden, caseUnionNotMatch }>`
🦴 *utilities*
🔢 *customizable*
Finds the type in tuple `A` that matches `Criteria`.
```ts
import type { TuplePlus } from 'type-plus'
type R = TuplePlus.Find<[true, 1, 'x', 3], string> // 'x'
type R = TuplePlus.Find<[true, 1, 'x', 3], number> // 1
type R = TuplePlus.Find<[string, number, 1], 1> // widen: 1 | undefined
type R = TuplePlus.Find<[true, number | string], string> // unionNotMatch: string
type R = TuplePlus.Find<[true, 1, 'x'], 2> // never
// customization
type R = TuplePlus.Find<[number], 1, { widen: false }> // never
type R = TuplePlus.Find<[number], 1, { caseWiden: never }> // never
type R = TuplePlus.Find<string[], 1, { caseArray: 2 }> // 2
type R = TuplePlus.Find<[], 1, { caseEmptyTuple: 2 }> // 2
type R = TuplePlus.Find<never, 1, { caseNever: 2 }> // 2
type R = TuplePlus.Find<[string], number, { caseNotMatch: 2 }> // 2
type R = TuplePlus.Find<[string | number], number, { caseUnionNotMatch: undefined }> // number | undefined
```
### [TuplePlus.PadStart](./tuple_plus.pad_start.ts)
`TuplePlus.PadStart<T, MaxLength, PadWith>`
⚗️ *transform*
Pad `T` with `PadWith` at the start of the tuple.
If the `MaxLength` is less than the length of the tuple,
the `Tuple` will be returned unchanged.
```ts
PadStart<[1, 2, 3], 5, 0> // [0, 0, 1, 2, 3]
// Ignore if MaxLength is less than the length of the tuple
PadStart<[1, 2, 3], 2> // [1, 2, 3]
// Default to unknown
PadStart<[1, 2, 3], 5> // [unknown, unknown, 1, 2, 3]
```
## References
- [Handbook]
[handbook]: https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types