Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

typescript-tuple

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typescript-tuple - npm Package Compare versions

Comparing version 1.2.1 to 1.3.0

64

index.d.ts
/**
* Choose type base on whether or not a tuple is finite
* @example `IsFinite<[0, 1, 2]>` → `true`
* @example `IsFinite<[0, 1, 2, ...number[]]>` → `false`
* @example `IsFinite<[0], 'Finite', 'Infinite'>` → `'Finite'`
* @example `IsFinite<[0, ...number[]], 'Finite', 'Infinite'>` → `Infinite`
*/
export declare type IsFinite<Tuple extends any[], Finite = true, Infinite = false> = utils.IsFinite<Tuple, Finite, Infinite>;
/**
* Get type of first element

@@ -43,2 +51,7 @@ * @example `First<[0, 1, 2]>` → `0`

export declare namespace utils {
type IsFinite<Tuple extends any[], Finite, Infinite> = {
empty: Finite;
nonEmpty: ((..._: Tuple) => any) extends ((_: infer First, ..._1: infer Rest) => any) ? IsFinite<Rest, Finite, Infinite> : never;
infinite: Infinite;
}[Tuple extends [] ? 'empty' : Tuple extends (infer Element)[] ? Element[] extends Tuple ? 'infinite' : 'nonEmpty' : never];
type Last<Tuple extends any[], Default = never> = {

@@ -48,3 +61,4 @@ empty: Default;

multi: ((..._: Tuple) => any) extends ((_: any, ..._1: infer Next) => any) ? Last<Next> : Default;
}[Tuple extends [] ? 'empty' : Tuple extends [any] ? 'single' : 'multi'];
infinite: Tuple extends (infer Element)[] ? Element : never;
}[Tuple extends [] ? 'empty' : Tuple extends [any] ? 'single' : Tuple extends (infer Element)[] ? Element[] extends Tuple ? 'infinite' : 'multi' : never];
type Prepend<Tuple extends any[], Addend> = ((_: Addend, ..._1: Tuple) => any) extends ((..._: infer Result) => any) ? Result : never;

@@ -54,3 +68,7 @@ type Reverse<Tuple extends any[], Prefix extends any[] = []> = {

nonEmpty: ((..._: Tuple) => any) extends ((_: infer First, ..._1: infer Next) => any) ? Reverse<Next, Prepend<Prefix, First>> : never;
}[Tuple extends [any, ...any[]] ? 'nonEmpty' : 'empty'];
infinite: {
ERROR: 'Cannot reverse an infinite tuple';
CODENAME: 'InfiniteTuple';
};
}[Tuple extends [any, ...any[]] ? IsFinite<Tuple, 'nonEmpty', 'infinite'> : 'empty'];
type Concat<Left extends any[], Right extends any[]> = {

@@ -60,11 +78,43 @@ emptyLeft: Right;

multiLeft: ((..._: Reverse<Left>) => any) extends ((_: infer LeftLast, ..._1: infer ReversedLeftRest) => any) ? Concat<Reverse<ReversedLeftRest>, Prepend<Right, LeftLast>> : never;
}[Left extends [] ? 'emptyLeft' : Left extends [any] ? 'singleLeft' : 'multiLeft'];
type Repeat<Type, Count extends number, Holder extends any[] = []> = {
infiniteLeft: {
ERROR: 'Left is not finite';
CODENAME: 'InfiniteLeft' & 'Infinite';
};
}[Left extends [] ? 'emptyLeft' : Left extends [any] ? 'singleLeft' : IsFinite<Left, 'multiLeft', 'infiniteLeft'>];
type Repeat<Type, Count extends number, Holder extends any[] = []> = number extends Count ? Type[] : {
fit: Holder;
unfit: Repeat<Type, Count, Prepend<Holder, Type>>;
}[Holder['length'] extends Count ? 'fit' : 'unfit'];
union: Count extends Holder['length'] | infer Rest ? Rest extends number ? Repeat<Type, Holder['length']> | Repeat<Type, Rest> : never : never;
}[Holder['length'] extends Count ? Count extends Holder['length'] ? 'fit' : 'union' : 'unfit'];
type ConcatMultiple<TupleSet extends any[][]> = {
empty: [];
multi: ((..._: Reverse<TupleSet>) => any) extends ((_: infer Last, ..._1: infer ReversedRest) => any) ? Last extends any[] ? ReversedRest extends any[][] ? Concat<ConcatMultiple<Reverse<ReversedRest>>, Last> : never : never : never;
}[TupleSet extends [] ? 'empty' : 'multi'];
nonEmpty: ((..._: Reverse<TupleSet>) => any) extends ((_: infer Last, ..._1: infer ReversedRest) => any) ? Last extends any[] ? ReversedRest extends any[][] ? Concat<ConcatMultiple<Reverse<ReversedRest>>, Last> : never : never : never;
infinite: {
ERROR: 'TupleSet is not finite';
CODENAME: 'InfiniteTupleSet' & 'Infinite';
};
}[TupleSet extends [] ? 'empty' : IsFinite<TupleSet, 'nonEmpty', 'infinite'>];
type SingleTupleSet<Types extends any[], Holder extends [any][] = []> = {
empty: Holder;
nonEmpty: ((..._: Reverse<Types>) => any) extends ((_: infer Last, ..._1: infer ReversedRest) => any) ? SingleTupleSet<Reverse<ReversedRest>, Prepend<Holder, [Last]>> : never;
}[Types extends [] ? 'empty' : 'nonEmpty'];
type FillTuple<Tuple extends any[], Replacement, Holder extends any[] = []> = {
empty: Holder;
nonEmpty: ((...a: Tuple) => any) extends ((a: infer First, ...b: infer Rest) => any) ? FillTuple<Rest, Replacement, Prepend<Holder, Replacement>> : never;
}[Tuple extends [] ? 'empty' : 'nonEmpty'];
type CompareLength<Left extends any[], Right extends any[]> = {
fitBoth: 'equal';
fitLeft: 'shorterLeft';
fitRight: 'shorterRight';
unfit: ((..._: Left) => any) extends ((_: any, ..._1: infer LeftRest) => any) ? ((..._: Right) => any) extends ((_: any, ..._1: infer RightRest) => any) ? CompareLength<LeftRest, RightRest> : never : never;
}[Left['length'] extends Right['length'] ? 'fitBoth' : Left extends [] ? 'fitLeft' : Right extends [] ? 'fitRight' : 'unfit'];
type SortTwoTuple<Left extends any[], Right extends any[], WhenEqual = [Left, Right]> = {
equal: WhenEqual;
shorterLeft: [Left, Right];
shorterRight: [Right, Left];
}[CompareLength<Left, Right>];
type ShortestTuple<TupleSet extends any[][], Shortest = any[]> = {
empty: Shortest;
nonEmpty: ((..._: TupleSet) => any) extends ((_: infer Head, ..._1: infer Tail) => any) ? Tail extends any[] ? Shortest extends any[] ? Head extends any[] ? ShortestTuple<Tail, SortTwoTuple<Shortest, Head>[0]> : never : never : never : never;
}[TupleSet extends [] ? 'empty' : 'nonEmpty'];
}

2

package.json
{
"name": "typescript-tuple",
"version": "1.2.1",
"version": "1.3.0",
"description": "Generics to work with tuples in TypeScript",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -11,2 +11,17 @@ # TypeScript Tuple

### `IsFinite`
```typescript
import { IsFinite } from 'typescript-tuple'
type Foo = IsFinite<[0, 1, 2]> // Expect: true
const foo: Foo = true
type Bar = IsFinite<[0, 1, 2, ...number[]]> // Expect: false
const bar: Bar = false
type Baz = IsFinite<[0, 1, 2], 'finite', 'infinite'> // Expect: 'finite'
const baz: Baz = 'finite'
```
### `First`

@@ -64,6 +79,22 @@

import { Repeat } from 'typescript-tuple'
type Foo = Repeat<['x'], 5> // Expect ['x', 'x', 'x', 'x', 'x']
// Basic
type Foo = Repeat<'x', 5> // Expect ['x', 'x', 'x', 'x', 'x']
const foo: Foo = ['x', 'x', 'x', 'x', 'x']
// Using union
type Bar = Repeat<'x', 1 | 3 | 4> // Expect ['x'] | ['x', 'x', 'x'] | ['x', 'x', 'x', 'x']
const bar1: Bar = ['x']
const bar3: Bar = ['x', 'x', 'x']
const bar4: Bar = ['x', 'x', 'x', 'x']
// Using ambiguous 'number' type
type Baz = Repeat<'x', number> // Expect 'x'[]
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`

@@ -70,0 +101,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc