TypeScript Tuple
Generics to work with tuples in TypeScript
Requirements
Usage
IsFinite
import { IsFinite } from 'typescript-tuple'
type Foo = IsFinite<[0, 1, 2]>
const foo: Foo = true
type Bar = IsFinite<[0, 1, 2, ...number[]]>
const bar: Bar = false
type Baz = IsFinite<[0, 1, 2], 'finite', 'infinite'>
const baz: Baz = 'finite'
SplitInfiniteTuple
import { SplitInfiniteTuple } from 'typescript-tuple'
type Foo = SplitInfiniteTuple<[0, 1, 2, ...number[]]>
type FinitePart = Foo[0]
type InfinitePart = Foo[1]
const foo: Foo = [[0, 1, 2], Array<number>()]
const finitePart: FinitePart = [0, 1, 2]
const infinitePart: InfinitePart = Array<number>()
First
import { First } from 'typescript-tuple'
type Foo = First<['a', 'b', 'c']>
const foo: Foo = 'a'
Last
import { Last } from 'typescript-tuple'
type Foo = Last<['a', 'b', 'c']>
const foo: Foo = 'c'
Tail
import { Tail } from 'typescript-tuple'
type Foo = Tail<['a', 'b', 'c']>
const foo: Foo = ['b', 'c']
FirstIndexEqual
import { FirstIndexEqual } from 'typescript-tuple'
type Foo = FirstIndexEqual<'x', ['a', 'x', 'b', 'x']>
const foo: Foo = 1
type Bar = FirstIndexEqual<'x', ['a', 'b']>
type Baz = FirstIndexEqual<'x', ['a', 'b'], 'not found'>
const baz: Baz = 'not found'
FirstIndexSubset
import { FirstIndexSubset } from 'typescript-tuple'
type Foo = FirstIndexSubset<string, [0, 'a', 1, 'b']>
const foo: Foo = 1
type Bar = FirstIndexSubset<string, [0, 1]>
type Baz = FirstIndexSubset<string, [0, 1], 'not found'>
const baz: Baz = 'not found'
FirstIndexSuperset
import { FirstIndexSuperset } from 'typescript-tuple'
type Foo = FirstIndexSuperset<'x', [number, string, 0 | 1, 'x' | 'y']>
const foo: Foo = 1
type Bar = FirstIndexSuperset<'x', [number, 0 | 1]>
type Baz = FirstIndexSuperset<'x', [number, 0 | 1], 'not found'>
const baz: Baz = 'not found'
LastIndexEqual
import { LastIndexEqual } from 'typescript-tuple'
type Foo = LastIndexEqual<'x', ['a', 'x', 'b', 'x']>
const foo: Foo = 3
type Bar = LastIndexEqual<'x', ['a', 'b']>
type Baz = LastIndexEqual<'x', ['a', 'b'], 'not found'>
const baz: Baz = 'not found'
LastIndexSubset
import { LastIndexSubset } from 'typescript-tuple'
type Foo = LastIndexSubset<string, [0, 'a', 1, 'b']>
const foo: Foo = 3
type Bar = LastIndexSubset<string, [0, 1]>
type Baz = LastIndexSubset<string, [0, 1], 'not found'>
const baz: Baz = 'not found'
LastIndexSuperset
import { LastIndexSuperset } from 'typescript-tuple'
type Foo = LastIndexSuperset<'x', [number, string, 0 | 1, 'x' | 'y']>
const foo: Foo = 3
type Bar = LastIndexSuperset<'x', [number, 0 | 1]>
type Baz = LastIndexSuperset<'x', [number, 0 | 1], 'not found'>
const baz: Baz = 'not found'
AllIndexesEqual
import { AllIndexesEqual } from 'typescript-tuple'
type Foo = AllIndexesEqual<'x', ['a', 'x', 'b', 'x']>
const foo: Foo = [1, 3]
type Bar = AllIndexesEqual<'x', ['a', 'x', 'b', ...'x'[]]>
const bar: Bar = [1, 3, 3, 3, 3]
AllIndexesSubset
import { AllIndexesSubset } from 'typescript-tuple'
type Foo = AllIndexesSubset<string, [0, 'a', 1, 'b']>
const foo: Foo = [1, 3]
type Bar = AllIndexesSubset<string, [0, 'a', 1, ...'b'[]]>
const bar: Bar = [1, 3, 3, 3, 3]
AllIndexesSuper
import { AllIndexesSuper } from 'typescript-tuple'
type Foo = AllIndexesSuper<'x', [number, string, 0 | 1, 'x' | 'y']>
const foo: Foo = [1, 3]
type Bar = AllIndexesSuper<'x', [number, string, 0 | 1, ...'x'[]]>
const bar: Bar = [1, 3, 3, 3, 3]
Append
import { Append } from 'typescript-tuple'
type Foo = Append<['a', 'b', 'c'], 'x'>
const foo: Foo = ['a', 'b', 'c', 'x']
Prepend
import { Prepend } from 'typescript-tuple'
type Foo = Prepend<['a', 'b', 'c'], 'x'>
const foo: Foo = ['x', 'a', 'b', 'c']
Reverse
import { Reverse } from 'typescript-tuple'
type Foo = Reverse<['a', 'b', 'c']>
const foo: Foo = ['c', 'b', 'a']
Concat
import { Concat } from 'typescript-tuple'
type Foo = Concat<['a', 'b', 'c'], [0, 1, 2]>
const foo: Foo = ['a', 'b', 'c', 0, 1, 2]
Repeat
import { Repeat } from 'typescript-tuple'
type Foo = Repeat<'x', 5>
const foo: Foo = ['x', 'x', 'x', 'x', 'x']
type Bar = Repeat<'x', 1 | 3 | 4>
const bar1: Bar = ['x']
const bar3: Bar = ['x', 'x', 'x']
const bar4: Bar = ['x', 'x', 'x', 'x']
type Baz = Repeat<'x', number>
const baz: Baz = Array<number>()
NOTES:
- Due to TypeScript design limitations, using floating point numbers and negative numbers might lead to infinite loop within TSC compiler, avoid doing this.
ConcatMultiple
import { ConcatMultiple } from 'typescript-tuple'
type Foo = ConcatMultiple<[[], ['a'], ['b', 'c']]>
const foo: Foo = ['a', 'b', 'c']
Drop
import { Drop } from 'typescript-tuple'
type Foo = Drop<[0, 1, 2, 3, 4], 2>
const foo: Foo = [2, 3, 4]
type Bar = Drop<[0, 1, 2, 3, 4, ...number[]], 2>
const bar: Bar = [2, 3, 4]
type Baz = Drop<[0, 1, 2, 3, 4], 10>
const baz: Baz = [2, 3, 4]
type Qux = Drop<[0, 1, 2, 3, 4, ...number[]], 10>
const qux: Qux = [2, 3, 4]
SliceStartQuantity
import { SliceStartQuantity } from 'typescript-tuple'
type Foo = SliceStartQuantity<[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 2, 4>
const foo: Foo = [2, 3, 4, 5]
SingleTupleSet
import { SingleTupleSet } from 'typescript-tuple'
type Foo = SingleTupleSet<[0, 1, 2]>
const foo: Foo = [[0], [1], [2]]
type Bar = SingleTupleSet<'x'[]>
const bar: Bar = Array<['x']>()
FillTuple
import { FillTuple } from 'typescript-tuple'
type Foo = FillTuple<[0, 1, 2, 3], 'r'>
const foo: Foo = ['r', 'r', 'r', 'r']
CompareLength
import { CompareLength } from 'typescript-tuple'
type Foo = CompareLength<[0, 1, 2], ['a', 'b', 'c']>
const foo: Foo = 'equal'
type Bar = CompareLength<[0, 1], ['a', 'b', 'c', 'd']>
const bar: Bar = 'shorterLeft'
type Baz = CompareLength<[0, 1, 2, 3], ['a', 'b']>
const baz: Baz = 'shorterRight'
SortTwoTuple
import { SortTwoTuple } from 'typescript-tuple'
type Foo = SortTwoTuple<[0, 1], ['a', 'b', 'c', 'd']>
const foo: Foo = [[0, 1], ['a', 'b', 'c', 'd']]
type Bar = SortTwoTuple<[0, 1, 2, 3], ['a', 'b']>
const bar: Bar = [['a', 'b'], [0, 1, 2, 3]]
type Baz = SortTwoTuple<[0, 1, 2], ['a', 'b', 'c', 'd']>
const baz: Baz = [[0, 1], 3, ['a', 'b', 'c']]
type Qux = SortTwoTuple<[0, 1, 2], ['a', 'b', 'c', 'd'], 'EQUAL'>
const qux: Qux = 'EQUAL'
ShortestTuple
import { ShortestTuple } from 'typescript-tuple'
type Foo = ShortestTuple<[[0, 1, 2], [false, true], ['a', 'b', 'c', 'd']]>
const foo: Foo = [false, true]
type Bar = ShortestTuple<[[0, 1, 2], ['a', 'b', 'c'], ...[false, true][]]>
const bar: Bar = [false, true]
LongestTuple
import { LongestTuple } from 'typescript-tuple'
type Foo = LongestTuple<[[0, 1, 2, 3], [false, true], ['a']]>
const foo: Foo = [0, 1, 2, 3]
type Bar = LongestTuple<[[], [false, true], ...[0, 1, 2][]]>
const bar: Bar = [0, 1, 2]
License
MIT @ Hoàng Văn Khải