+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Part 90 of 355

๐Ÿ”ข Type-Level Arrays: Tuple Manipulations

Master advanced array and tuple manipulations at the type level in TypeScript, creating powerful list processing algorithms and compile-time array operations ๐Ÿš€

๐Ÿ’ŽAdvanced
30 min read

Prerequisites

  • Expert knowledge of conditional types and template literal types ๐Ÿ“
  • Deep understanding of recursive type patterns and infer keyword โšก
  • Experience with advanced type-level programming techniques ๐Ÿ’ป

What you'll learn

  • Implement complex array algorithms at the type level ๐ŸŽฏ
  • Build tuple transformation and validation systems ๐Ÿ—๏ธ
  • Create compile-time list processors and array utilities ๐Ÿ›
  • Apply advanced array manipulation to real-world problems โœจ

๐ŸŽฏ Introduction

Welcome to the data structure laboratory of TypeScriptโ€™s type system! ๐Ÿ”ข This tutorial explores the fascinating world of type-level array and tuple manipulations, where youโ€™ll learn to build sophisticated list processing algorithms using only TypeScriptโ€™s type features.

Youโ€™ll discover how to implement complex array operations like mapping, filtering, reducing, and transforming entirely at compile time. Whether youโ€™re building data validation pipelines ๐Ÿ“Š, creating type-safe array utilities ๐Ÿ› ๏ธ, or implementing advanced functional programming patterns ๐Ÿงฎ, type-level array operations provide incredible power for compile-time list processing.

By the end of this tutorial, youโ€™ll be crafting array algorithms that run during compilation and building list processors that guarantee correctness at the type level! Letโ€™s manipulate some tuples! ๐Ÿง 

๐Ÿ“š Tuple Fundamentals and Array Types

๐Ÿค” Understanding Tuples vs Arrays

In TypeScriptโ€™s type system, tuples are fixed-length arrays with known element types, making them perfect for type-level manipulation:

// ๐ŸŒŸ Basic tuple types
type EmptyTuple = [];
type SingleElement = [string];
type Pair = [number, string];
type Triple = [boolean, number, string];

// ๐ŸŽฏ Array vs tuple differences
type StringArray = string[];           // Any number of strings
type StringTuple = [string, string];   // Exactly 2 strings

// โœจ Tuple with known length
type FixedArray = [1, 2, 3, 4, 5];
type ArrayLength = FixedArray['length']; // 5

// ๐Ÿ”„ Mixed type tuples
type MixedTuple = [string, number, boolean, symbol];
type FirstElement = MixedTuple[0];  // string
type SecondElement = MixedTuple[1]; // number

// ๐Ÿงช Tuple examples
type TupleTest1 = EmptyTuple['length'];    // 0
type TupleTest2 = Pair[0];                 // number
type TupleTest3 = Triple[2];               // string

๐Ÿ—๏ธ Tuple Construction and Destructuring

// ๐ŸŽฏ Head and tail operations
type Head<T extends readonly unknown[]> = 
  T extends readonly [infer H, ...unknown[]] ? H : never;

type Tail<T extends readonly unknown[]> = 
  T extends readonly [unknown, ...infer Rest] ? Rest : never;

type Last<T extends readonly unknown[]> = 
  T extends readonly [...unknown[], infer L] ? L : never;

type Init<T extends readonly unknown[]> = 
  T extends readonly [...infer Rest, unknown] ? Rest : never;

// ๐Ÿ” Tuple access examples
type HeadTest = Head<[1, 2, 3, 4]>;     // 1
type TailTest = Tail<[1, 2, 3, 4]>;     // [2, 3, 4]
type LastTest = Last<[1, 2, 3, 4]>;     // 4
type InitTest = Init<[1, 2, 3, 4]>;     // [1, 2, 3]

// ๐ŸŒŸ Tuple construction utilities
type Prepend<T, U extends readonly unknown[]> = [T, ...U];
type Append<T extends readonly unknown[], U> = [...T, U];

type PrependTest = Prepend<0, [1, 2, 3]>;   // [0, 1, 2, 3]
type AppendTest = Append<[1, 2, 3], 4>;     // [1, 2, 3, 4]

// ๐ŸŽจ Tuple concatenation
type Concat<T extends readonly unknown[], U extends readonly unknown[]> = [...T, ...U];

type ConcatTest = Concat<[1, 2], [3, 4]>;   // [1, 2, 3, 4]

// ๐Ÿ”„ Tuple repetition
type Repeat<T, N extends number, Acc extends unknown[] = []> = 
  Acc['length'] extends N ? Acc : Repeat<T, N, [...Acc, T]>;

type RepeatTest = Repeat<"x", 3>;           // ["x", "x", "x"]

๐Ÿงฎ Tuple Length and Index Operations

// ๐Ÿ“ Length utilities
type Length<T extends readonly unknown[]> = T['length'];

type IsEmpty<T extends readonly unknown[]> = T extends readonly [] ? true : false;

type HasLength<T extends readonly unknown[], N extends number> = 
  T['length'] extends N ? true : false;

// โœ… Length examples
type LengthTest = Length<[1, 2, 3]>;        // 3
type EmptyTest = IsEmpty<[]>;               // true
type HasLengthTest = HasLength<[1, 2], 2>;  // true

// ๐ŸŽฏ Index validation and access
type IsValidIndex<T extends readonly unknown[], I extends number> = 
  I extends keyof T ? true : false;

type At<T extends readonly unknown[], I extends number> = 
  I extends keyof T ? T[I] : never;

type SafeAt<T extends readonly unknown[], I extends number> = 
  IsValidIndex<T, I> extends true ? T[I] : undefined;

// ๐Ÿ” Index access examples
type AtTest1 = At<[10, 20, 30], 1>;         // 20
type AtTest2 = At<[10, 20, 30], 5>;         // never
type SafeAtTest = SafeAt<[10, 20, 30], 5>;  // undefined

// ๐Ÿ“Š Index range utilities
type Indices<T extends readonly unknown[]> = {
  [K in keyof T]: K
}[number];

type IndicesTest = Indices<["a", "b", "c"]>; // 0 | 1 | 2

// ๐Ÿ”„ Index transformation
type IndexPairs<T extends readonly unknown[]> = {
  [K in keyof T]: [K, T[K]]
}[number];

type IndexPairsTest = IndexPairs<["x", "y"]>; // [0, "x"] | [1, "y"]

๐Ÿ”„ Array Transformation Operations

๐ŸŽฏ Map Operation at Type Level

// ๐ŸŽจ Type-level map implementation
type Map<T extends readonly unknown[], F> = {
  [K in keyof T]: F extends (...args: any[]) => any
    ? F extends (arg: T[K]) => infer R
      ? R
      : never
    : F
};

// ๐ŸŒŸ String transformation mapper
type StringToLength<S> = S extends string ? S['length'] : never;
type StringToUpper<S> = S extends string ? Uppercase<S> : never;

type MapLengthTest = Map<["hi", "hello", "world"], StringToLength<any>>; 
// [2, 5, 5]

type MapUpperTest = Map<["hi", "hello"], StringToUpper<any>>; 
// ["HI", "HELLO"]

// ๐ŸŽฏ Number transformation mapper
type Double<N> = N extends number ? [N, N] : never;
type ToString<N> = N extends number ? `${N}` : never;

type MapDoubleTest = Map<[1, 2, 3], Double<any>>; 
// [[1, 1], [2, 2], [3, 3]]

type MapStringTest = Map<[1, 2, 3], ToString<any>>; 
// ["1", "2", "3"]

// ๐Ÿ”„ Complex object mapping
type AddId<T> = T & { id: string };
type WrapInArray<T> = [T];

type MapAddIdTest = Map<[{ name: "John" }, { name: "Jane" }], AddId<any>>;
// [{ name: "John"; id: string }, { name: "Jane"; id: string }]

// ๐ŸŽจ Conditional mapping
type MapIfString<T> = T extends string ? Uppercase<T> : T;

type ConditionalMapTest = Map<["hello", 42, "world"], MapIfString<any>>;
// ["HELLO", 42, "WORLD"]

// ๐ŸŒŸ Recursive deep mapping
type DeepMap<T, F> = T extends readonly (infer U)[]
  ? Map<T, F>
  : T extends readonly unknown[]
    ? { [K in keyof T]: DeepMap<T[K], F> }
    : F extends (...args: any[]) => any
      ? F extends (arg: T) => infer R
        ? R
        : T
      : T;

type DeepMapTest = DeepMap<[["a", "b"], ["c", "d"]], StringToUpper<any>>;
// [["A", "B"], ["C", "D"]]

๐Ÿ” Filter Operation at Type Level

// ๐ŸŽฏ Type-level filter implementation
type Filter<T extends readonly unknown[], F> = T extends readonly [infer First, ...infer Rest]
  ? F extends (arg: First) => any
    ? F extends (arg: First) => true
      ? [First, ...Filter<Rest, F>]
      : Filter<Rest, F>
    : F extends true
      ? [First, ...Filter<Rest, F>]
      : Filter<Rest, F>
  : [];

// ๐Ÿ” String filters
type IsString<T> = T extends string ? true : false;
type IsLongString<T> = T extends string 
  ? T['length'] extends 0 | 1 | 2 | 3 | 4 ? false : true
  : false;

type FilterStringsTest = Filter<[1, "hello", 2, "world", true], IsString<any>>;
// ["hello", "world"]

type FilterLongStringsTest = Filter<["hi", "hello", "a", "world"], IsLongString<any>>;
// ["hello", "world"]

// ๐ŸŽฏ Number filters
type IsEven<N> = N extends number 
  ? `${N}` extends `${string}${0 | 2 | 4 | 6 | 8}` ? true : false
  : false;

type IsPositive<N> = N extends number
  ? `${N}` extends `-${string}` ? false : true
  : false;

type FilterEvenTest = Filter<[1, 2, 3, 4, 5, 6], IsEven<any>>;
// [2, 4, 6]

type FilterPositiveTest = Filter<[-1, 2, -3, 4], IsPositive<any>>;
// [2, 4]

// ๐ŸŒŸ Object property filters
type HasProperty<T, K extends PropertyKey> = T extends Record<K, any> ? true : false;
type HasStringProperty<T> = T extends { [K in keyof T]: string } ? true : false;

type FilterWithName = Filter<
  [{ name: "John" }, { age: 30 }, { name: "Jane", age: 25 }], 
  HasProperty<any, "name">
>;
// [{ name: "John" }, { name: "Jane", age: 25 }]

// ๐ŸŽจ Complex filtering with multiple conditions
type IsStringAndLong<T> = T extends string 
  ? T['length'] extends 0 | 1 | 2 | 3 ? false : true 
  : false;

type ComplexFilterTest = Filter<
  ["hi", "hello", 42, "world", "a"], 
  IsStringAndLong<any>
>;
// ["hello", "world"]

// ๐Ÿ”„ Negation filter
type Not<F> = F extends true ? false : true;

type FilterNotStringsTest = Filter<[1, "hello", 2, "world"], Not<IsString<any>>>;
// [1, 2]

๐Ÿงฎ Reduce Operation at Type Level

// ๐ŸŽฏ Type-level reduce implementation
type Reduce<
  T extends readonly unknown[], 
  Reducer, 
  Initial = never,
  Acc = Initial> = T extends readonly [infer First, ...infer Rest]
  ? Reduce<Rest, Reducer, Initial, 
      Reducer extends (acc: Acc, current: First) => infer Result 
        ? Result 
        : Acc>
  : Acc;

// ๐Ÿงฎ Sum reducer
type Sum<Acc, Current> = Acc extends number
  ? Current extends number
    ? Add<Acc, Current>
    : Acc
  : Current extends number
    ? Current
    : 0;

// Helper for addition (simplified for small numbers)
type Add<A extends number, B extends number> = 
  A extends 0 ? B :
  B extends 0 ? A :
  A extends 1 ? B extends 1 ? 2 : B extends 2 ? 3 : B extends 3 ? 4 : never :
  A extends 2 ? B extends 1 ? 3 : B extends 2 ? 4 : B extends 3 ? 5 : never :
  A extends 3 ? B extends 1 ? 4 : B extends 2 ? 5 : B extends 3 ? 6 : never :
  never;

type SumTest = Reduce<[1, 2, 3], Sum<any, any>, 0>; // 6

// ๐Ÿ”— Concatenation reducer
type Concat<Acc, Current> = Acc extends string
  ? Current extends string
    ? `${Acc}${Current}`
    : Acc
  : Current extends string
    ? Current
    : "";

type ConcatTest = Reduce<["Hello", " ", "World"], Concat<any, any>, "">;
// "Hello World"

// ๐Ÿ“Š Array accumulation reducer
type ArrayAccumulator<Acc, Current> = Acc extends readonly unknown[]
  ? [...Acc, Current]
  : [Current];

type AccumulateTest = Reduce<[1, 2, 3], ArrayAccumulator<any, any>, []>;
// [1, 2, 3]

// ๐ŸŽฏ Object accumulation reducer
type ObjectAccumulator<Acc, Current> = Acc extends Record<string, unknown>
  ? Current extends Record<string, unknown>
    ? Acc & Current
    : Acc
  : Current extends Record<string, unknown>
    ? Current
    : {};

type ObjectTest = Reduce<
  [{ a: 1 }, { b: 2 }, { c: 3 }], 
  ObjectAccumulator<any, any>, 
  {}
>;
// { a: 1; b: 2; c: 3 }

// ๐ŸŒŸ Min/Max reducers
type Min<Acc, Current> = Acc extends number
  ? Current extends number
    ? Current extends 0 ? 0 :
      Current extends 1 ? Acc extends 0 ? 0 : 1 :
      Current extends 2 ? Acc extends 0 | 1 ? Acc : 2 :
      Current extends 3 ? Acc extends 0 | 1 | 2 ? Acc : 3 :
      Acc
    : Acc
  : Current;

type MinTest = Reduce<[3, 1, 4, 1, 5], Min<any, any>, never>;
// 1

// ๐Ÿ”„ Count reducer
type Counter<Acc, Current> = Acc extends number ? Add<Acc, 1> : 1;

type CountTest = Reduce<["a", "b", "c"], Counter<any, any>, 0>;
// 3

๐Ÿ” Array Search and Query Operations

๐ŸŽฏ Find and Search Operations

// ๐Ÿ” Find first element matching predicate
type Find<T extends readonly unknown[], Predicate> = T extends readonly [infer First, ...infer Rest]
  ? Predicate extends (arg: First) => true
    ? First
    : Find<Rest, Predicate>
  : never;

// ๐Ÿ“ Find index of element
type FindIndex<
  T extends readonly unknown[], 
  Predicate,
  Index extends number = 0> = T extends readonly [infer First, ...infer Rest]
  ? Predicate extends (arg: First) => true
    ? Index
    : FindIndex<Rest, Predicate, Add<Index, 1>>
  : never;

// ๐ŸŽฏ Find examples
type FindStringTest = Find<[1, "hello", 2, "world"], IsString<any>>;
// "hello"

type FindIndexTest = FindIndex<[1, "hello", 2, "world"], IsString<any>>;
// 1

// ๐Ÿ” Includes operation
type Includes<T extends readonly unknown[], U> = T extends readonly [infer First, ...infer Rest]
  ? First extends U
    ? true
    : Includes<Rest, U>
  : false;

type IncludesTest1 = Includes<[1, 2, 3], 2>;     // true
type IncludesTest2 = Includes<[1, 2, 3], 4>;     // false

// ๐ŸŽฏ Every and Some operations
type Every<T extends readonly unknown[], Predicate> = T extends readonly [infer First, ...infer Rest]
  ? Predicate extends (arg: First) => true
    ? Every<Rest, Predicate>
    : false
  : true;

type Some<T extends readonly unknown[], Predicate> = T extends readonly [infer First, ...infer Rest]
  ? Predicate extends (arg: First) => true
    ? true
    : Some<Rest, Predicate>
  : false;

// โœ… Every/Some examples
type EveryStringTest = Every<["a", "b", "c"], IsString<any>>;    // true
type EveryNumberTest = Every<["a", 1, "c"], IsString<any>>;      // false
type SomeStringTest = Some<[1, "hello", 2], IsString<any>>;      // true
type SomeNumberTest = Some<["a", "b", "c"], IsString<any>>;      // true

// ๐Ÿ”„ Count occurrences
type Count<T extends readonly unknown[], U, Acc extends number = 0> = T extends readonly [infer First, ...infer Rest]
  ? First extends U
    ? Count<Rest, U, Add<Acc, 1>>
    : Count<Rest, U, Acc>
  : Acc;

type CountTest = Count<[1, 2, 1, 3, 1], 1>;     // 3

// ๐ŸŽฏ Find all indices
type FindAllIndices<
  T extends readonly unknown[], 
  U,
  Acc extends number[] = [],
  Index extends number = 0> = T extends readonly [infer First, ...infer Rest]
  ? First extends U
    ? FindAllIndices<Rest, U, [...Acc, Index], Add<Index, 1>>
    : FindAllIndices<Rest, U, Acc, Add<Index, 1>>
  : Acc;

type FindAllTest = FindAllIndices<[1, 2, 1, 3, 1], 1>;
// [0, 2, 4]

๐Ÿงฉ Array Comparison and Set Operations

// ๐ŸŽฏ Array equality
type Equal<T extends readonly unknown[], U extends readonly unknown[]> = 
  T extends readonly [infer TFirst, ...infer TRest]
    ? U extends readonly [infer UFirst, ...infer URest]
      ? TFirst extends UFirst
        ? UFirst extends TFirst
          ? Equal<TRest, URest>
          : false
        : false
      : false
    : U extends readonly []
      ? true
      : false;

type EqualTest1 = Equal<[1, 2, 3], [1, 2, 3]>;     // true
type EqualTest2 = Equal<[1, 2, 3], [1, 2, 4]>;     // false

// ๐ŸŒŸ Remove duplicates (unique)
type Unique<T extends readonly unknown[], Acc extends readonly unknown[] = []> = 
  T extends readonly [infer First, ...infer Rest]
    ? Includes<Acc, First> extends true
      ? Unique<Rest, Acc>
      : Unique<Rest, [...Acc, First]>
    : Acc;

type UniqueTest = Unique<[1, 2, 2, 3, 1, 4]>;     // [1, 2, 3, 4]

// ๐Ÿ”— Union of arrays
type Union<T extends readonly unknown[], U extends readonly unknown[]> = 
  Unique<[...T, ...U]>;

type UnionTest = Union<[1, 2, 3], [3, 4, 5]>;     // [1, 2, 3, 4, 5]

// ๐ŸŽฏ Intersection of arrays
type Intersection<T extends readonly unknown[], U extends readonly unknown[]> = 
  Filter<T, (x: any) => Includes<U, any> extends true ? true : false>;

type IntersectionTest = Intersection<[1, 2, 3, 4], [3, 4, 5, 6]>; 
// [3, 4]

// ๐Ÿšซ Difference of arrays
type Difference<T extends readonly unknown[], U extends readonly unknown[]> = 
  Filter<T, (x: any) => Includes<U, any> extends true ? false : true>;

type DifferenceTest = Difference<[1, 2, 3, 4], [3, 4, 5, 6]>; 
// [1, 2]

// ๐Ÿ”„ Symmetric difference
type SymmetricDifference<T extends readonly unknown[], U extends readonly unknown[]> = 
  Union<Difference<T, U>, Difference<U, T>>;

type SymDiffTest = SymmetricDifference<[1, 2, 3], [3, 4, 5]>; 
// [1, 2, 4, 5]

// โœ… Subset checking
type IsSubset<T extends readonly unknown[], U extends readonly unknown[]> = 
  Every<T, (x: any) => Includes<U, any>>;

type SubsetTest1 = IsSubset<[1, 2], [1, 2, 3, 4]>;     // true
type SubsetTest2 = IsSubset<[1, 5], [1, 2, 3, 4]>;     // false

๐ŸŽจ Advanced Array Algorithms

๐Ÿ”„ Sorting and Ordering

// ๐ŸŽฏ Insertion sort (simplified for small arrays)
type InsertionSort<T extends readonly unknown[]> = T extends readonly [infer First, ...infer Rest]
  ? Insert<First, InsertionSort<Rest>>
  : [];

type Insert<X, Sorted extends readonly unknown[]> = Sorted extends readonly [infer First, ...infer Rest]
  ? X extends number
    ? First extends number
      ? X extends 0 ? [X, ...Sorted] :
        X extends 1 ? First extends 0 ? [First, X, ...Rest] : [X, ...Sorted] :
        X extends 2 ? First extends 0 | 1 ? [First, ...Insert<X, Rest>] : [X, ...Sorted] :
        [X, ...Sorted] // Simplified for demonstration
      : [X, ...Sorted]
    : [X, ...Sorted]
  : [X];

type SortTest = InsertionSort<[3, 1, 4, 1, 5]>; // Simplified result

// ๐Ÿ”„ Reverse operation
type Reverse<T extends readonly unknown[], Acc extends readonly unknown[] = []> = 
  T extends readonly [infer First, ...infer Rest]
    ? Reverse<Rest, [First, ...Acc]>
    : Acc;

type ReverseTest = Reverse<[1, 2, 3, 4]>;       // [4, 3, 2, 1]

// ๐ŸŽฏ Rotate array
type RotateLeft<T extends readonly unknown[], N extends number = 1> = 
  N extends 0 ? T :
  T extends readonly [infer First, ...infer Rest]
    ? RotateLeft<[...Rest, First], Subtract<N, 1>>
    : T;

// Helper for subtraction (simplified)
type Subtract<A extends number, B extends number> = 
  A extends 0 ? 0 :
  B extends 0 ? A :
  A extends 1 ? B extends 1 ? 0 : never :
  A extends 2 ? B extends 1 ? 1 : B extends 2 ? 0 : never :
  A extends 3 ? B extends 1 ? 2 : B extends 2 ? 1 : B extends 3 ? 0 : never :
  never;

type RotateTest = RotateLeft<[1, 2, 3, 4], 2>;  // [3, 4, 1, 2]

// ๐ŸŒŸ Shuffle indices (deterministic permutation)
type SwapAt<
  T extends readonly unknown[], 
  I extends number, 
  J extends number> = {
  [K in keyof T]: K extends `${I}` 
    ? T[J] 
    : K extends `${J}` 
      ? T[I] 
      : T[K]
};

type SwapTest = SwapAt<["a", "b", "c", "d"], 1, 3>; 
// ["a", "d", "c", "b"]

๐Ÿงฉ Matrix and 2D Array Operations

// ๐ŸŽฏ Matrix type definitions
type Matrix<T> = readonly (readonly T[])[];
type Vector<T> = readonly T[];

// ๐Ÿ“ Matrix dimensions
type Rows<M extends Matrix<unknown>> = M['length'];
type Cols<M extends Matrix<unknown>> = M extends readonly [infer FirstRow, ...unknown[]]
  ? FirstRow extends readonly unknown[]
    ? FirstRow['length']
    : 0
  : 0;

// ๐Ÿ”„ Matrix transpose
type Transpose<M extends Matrix<unknown>> = M extends readonly [infer FirstRow, ...infer RestRows]
  ? FirstRow extends readonly unknown[]
    ? RestRows extends Matrix<unknown>
      ? {
          [K in keyof FirstRow]: [FirstRow[K], ...GetColumn<RestRows, K>]
        }
      : { [K in keyof FirstRow]: [FirstRow[K]] }
    : []
  : [];

type GetColumn<M extends Matrix<unknown>, Col extends PropertyKey> = {
  [K in keyof M]: M[K] extends readonly unknown[] 
    ? Col extends keyof M[K] 
      ? M[K][Col] 
      : never
    : never
};

// โœ… Matrix transpose example
type TransposeTest = Transpose<[
  [1, 2, 3],
  [4, 5, 6]
]>; // [[1, 4], [2, 5], [3, 6]]

// ๐ŸŽฏ Matrix row and column access
type GetRow<M extends Matrix<unknown>, Row extends keyof M> = M[Row];
type GetCell<M extends Matrix<unknown>, Row extends keyof M, Col extends PropertyKey> = 
  M[Row] extends readonly unknown[]
    ? Col extends keyof M[Row]
      ? M[Row][Col]
      : never
    : never;

// ๐ŸŒŸ Flatten matrix
type Flatten<M extends Matrix<unknown>, Acc extends readonly unknown[] = []> = 
  M extends readonly [infer FirstRow, ...infer RestRows]
    ? FirstRow extends readonly unknown[]
      ? RestRows extends Matrix<unknown>
        ? Flatten<RestRows, [...Acc, ...FirstRow]>
        : [...Acc, ...FirstRow]
      : Acc
    : Acc;

type FlattenTest = Flatten<[[1, 2], [3, 4], [5, 6]]>; 
// [1, 2, 3, 4, 5, 6]

// ๐Ÿ”„ Reshape flat array to matrix
type Reshape<
  T extends readonly unknown[], 
  Rows extends number, 
  Cols extends number> = Length<T> extends Multiply<Rows, Cols>
  ? ReshapeHelper<T, Cols>
  : never;

type ReshapeHelper<
  T extends readonly unknown[], 
  Cols extends number,
  Acc extends Matrix<unknown> = []
> = T extends readonly []
  ? Acc
  : Take<T, Cols> extends infer Row
    ? Row extends readonly unknown[]
      ? Drop<T, Cols> extends infer Rest
        ? Rest extends readonly unknown[]
          ? ReshapeHelper<Rest, Cols, [...Acc, Row]>
          : Acc
        : Acc
      : Acc
    : Acc;

// Helper functions for reshape
type Take<T extends readonly unknown[], N extends number, Acc extends readonly unknown[] = []> = 
  Acc['length'] extends N ? Acc :
  T extends readonly [infer First, ...infer Rest]
    ? Take<Rest, N, [...Acc, First]>
    : Acc;

type Drop<T extends readonly unknown[], N extends number> = 
  N extends 0 ? T :
  T extends readonly [unknown, ...infer Rest]
    ? Drop<Rest, Subtract<N, 1>>
    : [];

// Simplified multiply for small numbers
type Multiply<A extends number, B extends number> = 
  A extends 0 ? 0 :
  A extends 1 ? B :
  A extends 2 ? B extends 1 ? 2 : B extends 2 ? 4 : B extends 3 ? 6 : never :
  A extends 3 ? B extends 1 ? 3 : B extends 2 ? 6 : B extends 3 ? 9 : never :
  never;

๐ŸŽฏ Sliding Window and Chunking

// ๐ŸชŸ Sliding window operation
type SlidingWindow<
  T extends readonly unknown[], 
  Size extends number,
  Acc extends readonly (readonly unknown[])[] = []
> = Take<T, Size> extends infer Window
  ? Window extends readonly unknown[]
    ? Length<Window> extends Size
      ? Drop<T, 1> extends infer Rest
        ? Rest extends readonly unknown[]
          ? Length<Rest> extends 0
            ? [...Acc, Window]
            : SlidingWindow<Rest, Size, [...Acc, Window]>
          : [...Acc, Window]
        : [...Acc, Window]
      : Acc
    : Acc
  : Acc;

type SlidingWindowTest = SlidingWindow<[1, 2, 3, 4, 5], 3>;
// [[1, 2, 3], [2, 3, 4], [3, 4, 5]]

// ๐Ÿงฉ Chunk array into fixed-size groups
type Chunk<
  T extends readonly unknown[], 
  Size extends number,
  Acc extends readonly (readonly unknown[])[] = []
> = T extends readonly []
  ? Acc
  : Take<T, Size> extends infer Group
    ? Group extends readonly unknown[]
      ? Drop<T, Size> extends infer Rest
        ? Rest extends readonly unknown[]
          ? Chunk<Rest, Size, [...Acc, Group]>
          : [...Acc, Group]
        : [...Acc, Group]
      : Acc
    : Acc;

type ChunkTest = Chunk<[1, 2, 3, 4, 5, 6, 7], 3>;
// [[1, 2, 3], [4, 5, 6], [7]]

// ๐ŸŽฏ Partition array by predicate
type Partition<T extends readonly unknown[], Predicate> = [
  Filter<T, Predicate>,
  Filter<T, Not<Predicate>>
];

type PartitionTest = Partition<[1, "a", 2, "b", 3], IsString<any>>;
// [["a", "b"], [1, 2, 3]]

// ๐ŸŒŸ Group by key function
type GroupBy<T extends readonly unknown[], KeyFn> = T extends readonly [infer First, ...infer Rest]
  ? KeyFn extends (arg: First) => infer Key
    ? {
        [K in Key]: Filter<T, (x: any) => KeyFn extends (arg: any) => K ? true : false>
      } & (Rest extends readonly unknown[] ? GroupBy<Rest, KeyFn> : {})
    : {}
  : {};

// Example: Group by string length
type GroupByLength<S> = S extends string ? S['length'] : never;

type GroupByTest = GroupBy<["hi", "hello", "a", "world"], GroupByLength<any>>;
// Complex result grouping strings by length

// ๐Ÿ”„ Zip arrays together
type Zip<T extends readonly unknown[], U extends readonly unknown[]> = T extends readonly [infer TFirst, ...infer TRest]
  ? U extends readonly [infer UFirst, ...infer URest]
    ? [[TFirst, UFirst], ...Zip<TRest, URest>]
    : []
  : [];

type ZipTest = Zip<[1, 2, 3], ["a", "b", "c"]>;
// [[1, "a"], [2, "b"], [3, "c"]]

// ๐ŸŽจ Zip with index
type ZipWithIndex<T extends readonly unknown[], Index extends number = 0> = T extends readonly [infer First, ...infer Rest]
  ? [[Index, First], ...ZipWithIndex<Rest, Add<Index, 1>>]
  : [];

type ZipWithIndexTest = ZipWithIndex<["a", "b", "c"]>;
// [[0, "a"], [1, "b"], [2, "c"]]

๐Ÿ›ก๏ธ Type-Safe Array Validation and Utilities

๐Ÿ” Array Shape Validation

// ๐ŸŽฏ Array shape validators
type IsHomogeneous<T extends readonly unknown[]> = T extends readonly []
  ? true
  : T extends readonly [infer First, ...infer Rest]
    ? Every<Rest, (x: any) => x extends First ? true : false>
    : false;

type IsFixed<T extends readonly unknown[], L extends number> = 
  T['length'] extends L ? true : false;

type IsNonEmpty<T extends readonly unknown[]> = 
  T extends readonly [] ? false : true;

// โœ… Shape validation examples
type HomogeneousTest1 = IsHomogeneous<[1, 2, 3]>;        // true
type HomogeneousTest2 = IsHomogeneous<[1, "a", 3]>;      // false
type FixedTest = IsFixed<[1, 2, 3], 3>;                  // true
type NonEmptyTest = IsNonEmpty<[]>;                       // false

// ๐Ÿ›ก๏ธ Type-safe array builders
type SafeArray<T, L extends number> = 
  readonly T[] & { length: L };

type SafeTuple<T extends readonly unknown[]> = 
  IsHomogeneous<T> extends true ? T : never;

type SafeNonEmpty<T extends readonly unknown[]> = 
  IsNonEmpty<T> extends true ? T : never;

// ๐ŸŽฏ Array bounds checking
type InBounds<T extends readonly unknown[], I extends number> = 
  IsValidIndex<T, I>;

type SafeAccess<T extends readonly unknown[], I extends number> = 
  InBounds<T, I> extends true ? T[I] : never;

// ๐ŸŒŸ Range validation
type InRange<N extends number, Min extends number, Max extends number> = 
  N extends Min ? true :
  N extends Max ? true :
  // Simplified range check
  N extends 0 ? Min extends 0 ? true : false :
  N extends 1 ? Min extends 0 | 1 ? Max extends 1 | 2 | 3 | 4 | 5 ? true : false : false :
  boolean;

type RangeTest = InRange<3, 1, 5>;                        // true

// ๐Ÿ”„ Array content validation
type AllStrings<T extends readonly unknown[]> = 
  Every<T, IsString<any>>;

type AllNumbers<T extends readonly unknown[]> = 
  Every<T, (x: any) => x extends number ? true : false>;

type AllOfType<T extends readonly unknown[], U> = 
  Every<T, (x: any) => x extends U ? true : false>;

// โœ… Content validation examples
type AllStringsTest = AllStrings<["a", "b", "c"]>;       // true
type AllNumbersTest = AllNumbers<[1, 2, "3"]>;           // false
type AllBoolTest = AllOfType<[true, false, true], boolean>; // true

๐ŸŽจ Advanced Array Utilities

// ๐Ÿ”„ Array interleaving
type Interleave<T extends readonly unknown[], U extends readonly unknown[]> = 
  T extends readonly [infer TFirst, ...infer TRest]
    ? U extends readonly [infer UFirst, ...infer URest]
      ? [TFirst, UFirst, ...Interleave<TRest, URest>]
      : T
    : U;

type InterleaveTest = Interleave<[1, 2, 3], ["a", "b", "c"]>;
// [1, "a", 2, "b", 3, "c"]

// ๐ŸŽฏ Cartesian product
type CartesianProduct<T extends readonly unknown[], U extends readonly unknown[]> = 
  T extends readonly [infer TFirst, ...infer TRest]
    ? [
        ...Map<U, (x: any) => [TFirst, any]>,
        ...(TRest extends readonly unknown[] ? CartesianProduct<TRest, U> : [])
      ]
    : [];

type CartesianTest = CartesianProduct<[1, 2], ["a", "b"]>;
// [[1, "a"], [1, "b"], [2, "a"], [2, "b"]]

// ๐ŸŒŸ Permutations (simplified for small arrays)
type Permutations<T extends readonly unknown[]> = T extends readonly []
  ? [[]]
  : T extends readonly [infer First, ...infer Rest]
    ? Rest extends readonly unknown[]
      ? InsertAtAllPositions<First, Permutations<Rest>>
      : []
    : [];

type InsertAtAllPositions<
  X,
  Perms extends readonly (readonly unknown[])[]
> = Perms extends readonly [infer FirstPerm, ...infer RestPerms]
  ? FirstPerm extends readonly unknown[]
    ? RestPerms extends readonly (readonly unknown[])[]
      ? [
          ...InsertAtPositions<X, FirstPerm>,
          ...InsertAtAllPositions<X, RestPerms>
        ]
      : InsertAtPositions<X, FirstPerm>
    : []
  : [];

type InsertAtPositions<X, T extends readonly unknown[], Index extends number = 0> = 
  Index extends T['length']
    ? [[...T, X]]
    : [
        [...Take<T, Index>, X, ...Drop<T, Index>],
        ...InsertAtPositions<X, T, Add<Index, 1>>
      ];

type PermTest = Permutations<[1, 2]>; // [[1, 2], [2, 1]]

// ๐Ÿงฎ Array statistics
type Min<T extends readonly number[]> = Reduce<T, Min<any, any>, never>;
type Max<T extends readonly number[]> = Reduce<T, Max<any, any>, never>;
type Sum<T extends readonly number[]> = Reduce<T, Sum<any, any>, 0>;

// ๐ŸŽฏ Array comparison utilities
type IsPrefix<Prefix extends readonly unknown[], T extends readonly unknown[]> = 
  Prefix extends readonly []
    ? true
    : Prefix extends readonly [infer PFirst, ...infer PRest]
      ? T extends readonly [infer TFirst, ...infer TRest]
        ? PFirst extends TFirst
          ? TFirst extends PFirst
            ? IsPrefix<PRest, TRest>
            : false
          : false
        : false
      : false;

type IsSuffix<Suffix extends readonly unknown[], T extends readonly unknown[]> = 
  IsPrefix<Suffix, Reverse<T>>;

type PrefixTest = IsPrefix<[1, 2], [1, 2, 3, 4]>;        // true
type SuffixTest = IsSuffix<[3, 4], [1, 2, 3, 4]>;        // true

// ๐Ÿ” Array subsequence checking
type IsSubsequence<Sub extends readonly unknown[], T extends readonly unknown[]> = 
  Sub extends readonly []
    ? true
    : Sub extends readonly [infer SubFirst, ...infer SubRest]
      ? T extends readonly [infer TFirst, ...infer TRest]
        ? SubFirst extends TFirst
          ? TFirst extends SubFirst
            ? IsSubsequence<SubRest, TRest>
            : IsSubsequence<Sub, TRest>
          : IsSubsequence<Sub, TRest>
        : false
      : false;

type SubsequenceTest = IsSubsequence<[1, 3, 5], [1, 2, 3, 4, 5]>; // true

๐ŸŽ“ Key Takeaways

Youโ€™ve mastered the array manipulation capabilities of TypeScriptโ€™s type system! Hereโ€™s what you now command:

  • โœ… Tuple fundamentals including construction, destructuring, and access ๐Ÿ’ช
  • โœ… Array transformations with map, filter, and reduce operations ๐Ÿ›ก๏ธ
  • โœ… Search and query operations for finding and analyzing elements ๐ŸŽฏ
  • โœ… Advanced algorithms including sorting, matrix operations, and windowing ๐Ÿ›
  • โœ… Type-safe validation and array shape checking ๐Ÿš€
  • โœ… Complex utilities for permutations, products, and statistical operations โœจ
  • โœ… Real-world applications in data processing and validation pipelines ๐Ÿ”„

Remember: Type-level array operations enable you to build incredibly powerful compile-time data processors! ๐Ÿค

๐Ÿค Next Steps

Congratulations! ๐ŸŽ‰ Youโ€™ve become a master of array manipulation in TypeScriptโ€™s type system!

Hereโ€™s what to do next:

  1. ๐Ÿ’ป Build data validation pipelines with compile-time array processing
  2. ๐Ÿ—๏ธ Create type-safe array utilities and functional programming patterns
  3. ๐Ÿ“š Move on to our next tutorial: Type Predicates - User-Defined Type Guards
  4. ๐ŸŒŸ Implement matrix operations and linear algebra in the type system
  5. ๐Ÿ” Explore advanced functional programming patterns with type-level arrays
  6. ๐ŸŽฏ Build intelligent data transformation and ETL systems
  7. ๐Ÿš€ Push the boundaries of compile-time data processing

Remember: You now possess the power to manipulate arrays and data structures entirely at the type level! Use this knowledge to build incredibly safe and intelligent data systems. ๐Ÿš€


Happy array manipulating! ๐ŸŽ‰๐Ÿ”ขโœจ