or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

array-tuple-types.mdbasic-types.mdchange-case-types.mddeep-wrapper-types.mdfunction-types.mdindex.mdkey-types.mdmark-wrapper-types.mdtype-checkers.mdutility-functions.mdutility-types.md

array-tuple-types.mddocs/

0

# Array & Tuple Types

1

2

Specialized types for working with arrays, tuples, and array-like structures with type safety. These utilities help you manipulate and constrain array types effectively.

3

4

## Capabilities

5

6

### AnyArray

7

8

Matches `Array<Type>` or `ReadonlyArray<Type>` where `Type` is `any` by default.

9

10

```typescript { .api }

11

type AnyArray<Type = any> = Array<Type> | ReadonlyArray<Type>;

12

```

13

14

**Usage Example:**

15

16

```typescript

17

import type { AnyArray } from "ts-essentials";

18

19

type StringArrays = AnyArray<string>; // Array<string> | ReadonlyArray<string>

20

21

function processArray<T>(arr: AnyArray<T>): T[] {

22

return Array.from(arr);

23

}

24

25

// Works with both mutable and readonly arrays

26

processArray([1, 2, 3]); // Array<number>

27

processArray(["a", "b"] as const); // readonly string[]

28

```

29

30

### ArrayOrSingle

31

32

Matches `Type` or `Type[]`, useful for APIs that accept either a single value or an array.

33

34

```typescript { .api }

35

type ArrayOrSingle<Type> = Type | Type[];

36

```

37

38

**Usage Example:**

39

40

```typescript

41

import type { ArrayOrSingle } from "ts-essentials";

42

43

function addTags(tags: ArrayOrSingle<string>): string[] {

44

return Array.isArray(tags) ? tags : [tags];

45

}

46

47

// Both calls are valid

48

addTags("javascript"); // Works with single string

49

addTags(["javascript", "typescript"]); // Works with array

50

51

// API design example

52

interface SearchOptions {

53

query: string;

54

categories: ArrayOrSingle<string>;

55

sort: ArrayOrSingle<"date" | "relevance">;

56

}

57

```

58

59

### ReadonlyArrayOrSingle

60

61

Matches `Type` or `readonly Type[]`, similar to `ArrayOrSingle` but with readonly constraint.

62

63

```typescript { .api }

64

type ReadonlyArrayOrSingle<Type> = Type | readonly Type[];

65

```

66

67

**Usage Example:**

68

69

```typescript

70

import type { ReadonlyArrayOrSingle } from "ts-essentials";

71

72

function processReadonlyData<T>(data: ReadonlyArrayOrSingle<T>): readonly T[] {

73

return Array.isArray(data) ? data : [data] as const;

74

}

75

76

// Usage with readonly arrays

77

const result = processReadonlyData(["a", "b"] as const);

78

// result is readonly string[]

79

```

80

81

### ElementOf

82

83

Constructs a type which equals to array element type for type `Type`.

84

85

```typescript { .api }

86

type ElementOf<Type> = Type extends ReadonlyArray<infer U> ? U : never;

87

```

88

89

**Usage Example:**

90

91

```typescript

92

import type { ElementOf } from "ts-essentials";

93

94

type StringArray = string[];

95

type ArrayElement = ElementOf<StringArray>; // string

96

97

type TupleArray = [number, string, boolean];

98

type TupleElement = ElementOf<TupleArray>; // number | string | boolean

99

100

// Useful for generic functions working with array elements

101

function processElements<T extends ReadonlyArray<any>>(

102

arr: T,

103

processor: (element: ElementOf<T>) => ElementOf<T>

104

): T {

105

return arr.map(processor) as T;

106

}

107

108

const numbers = [1, 2, 3];

109

const doubled = processElements(numbers, x => x * 2); // number[]

110

```

111

112

### Head

113

114

Constructs a type which equals to first element in type `Type`.

115

116

```typescript { .api }

117

type Head<Type extends ReadonlyArray<any>> = Type extends readonly [infer H, ...any[]] ? H : never;

118

```

119

120

**Usage Example:**

121

122

```typescript

123

import type { Head } from "ts-essentials";

124

125

type Tuple = [string, number, boolean];

126

type FirstElement = Head<Tuple>; // string

127

128

type EmptyTuple = [];

129

type EmptyHead = Head<EmptyTuple>; // never

130

131

// Runtime helper function

132

function getHead<T extends ReadonlyArray<any>>(arr: T): Head<T> | undefined {

133

return arr[0] as Head<T> | undefined;

134

}

135

136

const tuple = ["hello", 42, true] as const;

137

const head = getHead(tuple); // "hello"

138

```

139

140

### Tail

141

142

Constructs a type which equals to elements but first one in type `Type`.

143

144

```typescript { .api }

145

type Tail<Type extends ReadonlyArray<any>> = Type extends readonly [any, ...infer T] ? T : [];

146

```

147

148

**Usage Example:**

149

150

```typescript

151

import type { Tail } from "ts-essentials";

152

153

type Tuple = [string, number, boolean];

154

type RestElements = Tail<Tuple>; // [number, boolean]

155

156

type SingleTuple = [string];

157

type SingleTail = Tail<SingleTuple>; // []

158

159

// Runtime helper function

160

function getTail<T extends ReadonlyArray<any>>(arr: T): Tail<T> {

161

return arr.slice(1) as Tail<T>;

162

}

163

164

const tuple = ["hello", 42, true] as const;

165

const tail = getTail(tuple); // [42, true]

166

```

167

168

### NonEmptyArray

169

170

Matches array with at least one element of type `Type`.

171

172

```typescript { .api }

173

type NonEmptyArray<Type> = [Type, ...Type[]];

174

```

175

176

**Usage Example:**

177

178

```typescript

179

import type { NonEmptyArray } from "ts-essentials";

180

181

function processNonEmptyArray<T>(arr: NonEmptyArray<T>): T {

182

return arr[0]; // Safe to access first element

183

}

184

185

// Type-safe functions that require non-empty arrays

186

function findMax(numbers: NonEmptyArray<number>): number {

187

return Math.max(...numbers);

188

}

189

190

// This works

191

findMax([1, 2, 3]); // OK

192

193

// This would cause a compile error:

194

// findMax([]); // Error: Argument of type '[]' is not assignable

195

196

// Type guard for runtime checking

197

function isNonEmptyArray<T>(arr: T[]): arr is NonEmptyArray<T> {

198

return arr.length > 0;

199

}

200

201

function safeProcessArray<T>(arr: T[]): T | undefined {

202

if (isNonEmptyArray(arr)) {

203

return processNonEmptyArray(arr); // Type-safe!

204

}

205

return undefined;

206

}

207

```

208

209

### Tuple

210

211

Matches type constraint for tuple with elements of type `Type` (`any` by default).

212

213

```typescript { .api }

214

type Tuple<Type = any> = readonly Type[];

215

```

216

217

**Usage Example:**

218

219

```typescript

220

import type { Tuple } from "ts-essentials";

221

222

// Generic tuple constraint

223

function processTuple<T extends Tuple>(tuple: T): T {

224

return tuple;

225

}

226

227

// Works with any tuple

228

processTuple([1, 2, 3] as const);

229

processTuple(["a", "b"] as const);

230

231

// Typed tuple constraint

232

function processStringTuple<T extends Tuple<string>>(tuple: T): T {

233

return tuple;

234

}

235

236

processTuple(["hello", "world"] as const); // OK

237

// processTuple([1, 2] as const); // Error: not all elements are strings

238

```

239

240

## Advanced Usage

241

242

Combine array and tuple utilities for complex operations:

243

244

```typescript

245

import type {

246

NonEmptyArray,

247

Head,

248

Tail,

249

ElementOf,

250

ArrayOrSingle

251

} from "ts-essentials";

252

253

// Recursive tuple processing

254

type ProcessTuple<T extends ReadonlyArray<any>> = T extends NonEmptyArray<any>

255

? [ProcessElement<Head<T>>, ...ProcessTuple<Tail<T>>]

256

: [];

257

258

type ProcessElement<T> = T extends string ? `processed_${T}` : T;

259

260

type Example = ProcessTuple<["hello", "world", 42]>;

261

// Result: ["processed_hello", "processed_world", 42]

262

263

// Safe array operations

264

function safeArrayOperation<T extends ReadonlyArray<any>>(

265

arr: T

266

): {

267

first: Head<T> | undefined;

268

rest: Tail<T>;

269

elementType: ElementOf<T> | undefined

270

} {

271

return {

272

first: arr[0] as Head<T> | undefined,

273

rest: arr.slice(1) as Tail<T>,

274

elementType: arr[0] as ElementOf<T> | undefined

275

};

276

}

277

278

// Flexible input handling

279

function flexibleInput<T>(input: ArrayOrSingle<T>): NonEmptyArray<T> | never {

280

const arr = Array.isArray(input) ? input : [input];

281

if (arr.length === 0) {

282

throw new Error("Input cannot be empty");

283

}

284

return arr as NonEmptyArray<T>;

285

}

286

```

287

288

## Types

289

290

```typescript { .api }

291

type ReadonlyArray<T> = readonly T[];

292

type Array<T> = T[];

293

```