or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdbuiltin-types.mdcollection-types.mdindex.mdobject-array-validation.mdprimitive-types.mdtyped-arrays.md

collection-types.mddocs/

0

# Collection Type Validation

1

2

Validation for JavaScript collection types including Map, Set, WeakMap, WeakSet, and Iterable objects with size constraints and content validation.

3

4

## Capabilities

5

6

### Set Validation

7

8

Validation for Set objects with size constraints and content checking methods.

9

10

```typescript { .api }

11

/** Set validation predicate */

12

interface SetPredicate extends BasePredicate<Set<unknown>> {

13

// Size validation

14

size(size: number): SetPredicate;

15

minSize(size: number): SetPredicate;

16

maxSize(size: number): SetPredicate;

17

18

// Content validation

19

has<T>(...items: T[]): SetPredicate;

20

hasAny<T>(...items: T[]): SetPredicate;

21

deepEqual<T>(expected: Set<T>): SetPredicate;

22

ofType<T>(predicate: Predicate<T>): SetPredicate;

23

24

// State validation

25

readonly empty: SetPredicate;

26

readonly nonEmpty: SetPredicate;

27

}

28

```

29

30

**Usage Examples:**

31

32

```typescript

33

import ow from 'ow';

34

35

// Size validation

36

ow(new Set([1, 2, 3]), ow.set.size(3));

37

ow(new Set([1, 2]), ow.set.minSize(2));

38

ow(new Set([1, 2, 3]), ow.set.maxSize(5));

39

ow(new Set(), ow.set.empty);

40

ow(new Set([1]), ow.set.nonEmpty);

41

42

// Content validation

43

const numbers = new Set([1, 2, 3, 4, 5]);

44

ow(numbers, ow.set.has(1, 3, 5));

45

ow(numbers, ow.set.hasAny(2, 10, 20));

46

47

// Deep equality

48

ow(new Set([1, 2, 3]), ow.set.deepEqual(new Set([3, 2, 1])));

49

50

// Type validation - all values must match predicate

51

ow(new Set([1, 2, 3]), ow.set.ofType(ow.number.positive));

52

ow(new Set(['a', 'b', 'c']), ow.set.ofType(ow.string.alphabetical));

53

54

// Complex objects in sets

55

const userSet = new Set([

56

{ id: 1, name: 'Alice' },

57

{ id: 2, name: 'Bob' }

58

]);

59

60

ow(userSet, ow.set.ofType(ow.object.exactShape({

61

id: ow.number.integer.positive,

62

name: ow.string.nonEmpty

63

})));

64

```

65

66

### Map Validation

67

68

Validation for Map objects with size constraints and key/value validation methods.

69

70

```typescript { .api }

71

/** Map validation predicate */

72

interface MapPredicate extends BasePredicate<Map<unknown, unknown>> {

73

// Size validation

74

size(size: number): MapPredicate;

75

minSize(size: number): MapPredicate;

76

maxSize(size: number): MapPredicate;

77

78

// Key validation

79

hasKeys<T1>(...keys: T1[]): MapPredicate;

80

hasAnyKeys<T1>(...keys: T1[]): MapPredicate;

81

keysOfType<T1>(predicate: Predicate<T1>): MapPredicate;

82

83

// Value validation

84

hasValues<T2>(...values: T2[]): MapPredicate;

85

hasAnyValues<T2>(...values: T2[]): MapPredicate;

86

valuesOfType<T2>(predicate: Predicate<T2>): MapPredicate;

87

88

// Equality validation

89

deepEqual<T1, T2>(expected: Map<T1, T2>): MapPredicate;

90

91

// State validation

92

readonly empty: MapPredicate;

93

readonly nonEmpty: MapPredicate;

94

}

95

```

96

97

**Usage Examples:**

98

99

```typescript

100

import ow from 'ow';

101

102

// Size validation

103

const userMap = new Map([

104

['alice', { age: 30 }],

105

['bob', { age: 25 }],

106

['charlie', { age: 35 }]

107

]);

108

109

ow(userMap, ow.map.size(3));

110

ow(userMap, ow.map.minSize(2));

111

ow(userMap, ow.map.maxSize(5));

112

ow(new Map(), ow.map.empty);

113

ow(userMap, ow.map.nonEmpty);

114

115

// Key and value validation

116

ow(userMap, ow.map.hasKeys('alice', 'bob'));

117

ow(userMap, ow.map.hasAnyKeys('alice', 'david'));

118

ow(userMap, ow.map.hasValues({ age: 30 }, { age: 25 }));

119

ow(userMap, ow.map.hasAnyValues({ age: 30 }, { age: 50 }));

120

121

// Type validation

122

ow(userMap, ow.map.keysOfType(ow.string.nonEmpty));

123

ow(userMap, ow.map.valuesOfType(ow.object.exactShape({

124

age: ow.number.integer.positive

125

})));

126

127

// Deep equality

128

const expectedMap = new Map([

129

['alice', { age: 30 }],

130

['bob', { age: 25 }]

131

]);

132

133

ow(expectedMap, ow.map.deepEqual(expectedMap));

134

135

// Number-keyed maps

136

const scoreMap = new Map([

137

[1, 'Alice'],

138

[2, 'Bob'],

139

[3, 'Charlie']

140

]);

141

142

ow(scoreMap, ow.map.keysOfType(ow.number.integer.positive));

143

ow(scoreMap, ow.map.valuesOfType(ow.string.nonEmpty));

144

```

145

146

### WeakSet Validation

147

148

Validation for WeakSet objects with content checking methods.

149

150

```typescript { .api }

151

/** WeakSet validation predicate */

152

interface WeakSetPredicate extends BasePredicate<WeakSet<object>> {

153

/** WeakSet must contain all specified items */

154

has<T>(...items: T[]): WeakSetPredicate;

155

156

/** WeakSet must contain any of the specified items */

157

hasAny<T>(...items: T[]): WeakSetPredicate;

158

}

159

```

160

161

**Usage Examples:**

162

163

```typescript

164

import ow from 'ow';

165

166

const obj1 = { id: 1 };

167

const obj2 = { id: 2 };

168

const obj3 = { id: 3 };

169

170

const weakSet = new WeakSet([obj1, obj2]);

171

172

// Basic WeakSet validation

173

ow(weakSet, ow.weakSet);

174

175

// Content validation

176

ow(weakSet, ow.weakSet.has(obj1, obj2));

177

ow(weakSet, ow.weakSet.hasAny(obj1, obj3));

178

179

// Note: WeakSet doesn't support size methods due to its weak nature

180

```

181

182

### WeakMap Validation

183

184

Validation for WeakMap objects with key validation methods.

185

186

```typescript { .api }

187

/** WeakMap validation predicate */

188

interface WeakMapPredicate extends BasePredicate<WeakMap<object, unknown>> {

189

/** WeakMap must contain all specified keys */

190

hasKeys<KeyType>(...keys: KeyType[]): WeakMapPredicate;

191

192

/** WeakMap must contain any of the specified keys */

193

hasAnyKeys<KeyType>(...keys: KeyType[]): WeakMapPredicate;

194

}

195

```

196

197

**Usage Examples:**

198

199

```typescript

200

import ow from 'ow';

201

202

const keyObj1 = { id: 'key1' };

203

const keyObj2 = { id: 'key2' };

204

const keyObj3 = { id: 'key3' };

205

206

const weakMap = new WeakMap([

207

[keyObj1, 'value1'],

208

[keyObj2, 'value2']

209

]);

210

211

// Basic WeakMap validation

212

ow(weakMap, ow.weakMap);

213

214

// Key validation

215

ow(weakMap, ow.weakMap.hasKeys(keyObj1, keyObj2));

216

ow(weakMap, ow.weakMap.hasAnyKeys(keyObj1, keyObj3));

217

218

// Note: WeakMap doesn't support value validation or size methods due to its weak nature

219

```

220

221

### Iterable Validation

222

223

Validation for objects that implement the Iterable interface.

224

225

```typescript { .api }

226

/** Iterable validation predicate */

227

const iterable: Predicate<Iterable<unknown>>;

228

```

229

230

**Usage Examples:**

231

232

```typescript

233

import ow from 'ow';

234

235

// Basic iterables

236

ow([1, 2, 3], ow.iterable);

237

ow('hello', ow.iterable);

238

ow(new Set([1, 2, 3]), ow.iterable);

239

ow(new Map([['a', 1]]), ow.iterable);

240

241

// Custom iterables

242

const customIterable = {

243

*[Symbol.iterator]() {

244

yield 1;

245

yield 2;

246

yield 3;

247

}

248

};

249

250

ow(customIterable, ow.iterable);

251

252

// Generator functions

253

function* numberGenerator() {

254

yield 1;

255

yield 2;

256

yield 3;

257

}

258

259

ow(numberGenerator(), ow.iterable);

260

```

261

262

## Advanced Usage Examples

263

264

### Collection Transformation Validation

265

266

```typescript

267

import ow from 'ow';

268

269

// Validate data transformation using collections

270

function processUniqueItems(items: unknown[]): Set<string> {

271

ow(items, ow.array.ofType(ow.string.nonEmpty));

272

273

const uniqueItems = new Set(items as string[]);

274

275

ow(uniqueItems, ow.set.nonEmpty);

276

ow(uniqueItems, ow.set.ofType(ow.string.nonEmpty));

277

278

return uniqueItems;

279

}

280

281

// Usage

282

const result = processUniqueItems(['apple', 'banana', 'apple', 'cherry']);

283

console.log(result); // Set(3) { 'apple', 'banana', 'cherry' }

284

```

285

286

### Caching Pattern Validation

287

288

```typescript

289

import ow from 'ow';

290

291

class Cache<K, V> {

292

private store = new Map<K, V>();

293

294

set(key: K, value: V): void {

295

ow(key, 'cacheKey', ow.any(ow.string, ow.number));

296

this.store.set(key, value);

297

298

// Validate store state

299

ow(this.store, ow.map.nonEmpty);

300

}

301

302

get(key: K): V | undefined {

303

ow(this.store, ow.map.hasKeys(key));

304

return this.store.get(key);

305

}

306

307

size(): number {

308

return this.store.size;

309

}

310

}

311

312

// Usage

313

const cache = new Cache<string, number>();

314

cache.set('count', 42);

315

ow(cache.size(), ow.number.equal(1));

316

```

317

318

### Data Structure Validation

319

320

```typescript

321

import ow from 'ow';

322

323

// Validate complex data structures

324

interface GraphNode {

325

id: string;

326

connections: Set<string>;

327

}

328

329

function validateGraph(nodes: Map<string, GraphNode>) {

330

// Validate map structure

331

ow(nodes, ow.map.nonEmpty);

332

ow(nodes, ow.map.keysOfType(ow.string.nonEmpty));

333

334

// Validate each node

335

ow(nodes, ow.map.valuesOfType(ow.object.exactShape({

336

id: ow.string.nonEmpty,

337

connections: ow.set.ofType(ow.string.nonEmpty)

338

})));

339

340

// Validate that all connections reference existing nodes

341

for (const [nodeId, node] of nodes) {

342

ow(nodeId, ow.string.equals(node.id));

343

344

for (const connectionId of node.connections) {

345

ow(nodes, ow.map.hasKeys(connectionId));

346

}

347

}

348

}

349

```

350

351

### Memory-Efficient Collections

352

353

```typescript

354

import ow from 'ow';

355

356

// Using WeakMap for memory-efficient object metadata

357

const objectMetadata = new WeakMap();

358

359

function attachMetadata(obj: object, metadata: any) {

360

ow(obj, ow.object);

361

ow(metadata, ow.object.hasKeys('timestamp', 'type'));

362

363

objectMetadata.set(obj, metadata);

364

365

ow(objectMetadata, ow.weakMap.hasKeys(obj));

366

}

367

368

// Usage

369

const myObject = { data: 'example' };

370

attachMetadata(myObject, { timestamp: Date.now(), type: 'example' });

371

```