or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assertions.mdasync.mdcollections.mdindex.mdnumbers.mdobjects.mdprimitives.mdstrings.mdtyped-arrays.mdvalidation.mdweb-apis.md

collections.mddocs/

0

# Collections and Emptiness

1

2

Specialized checks for empty and non-empty collections including arrays, objects, strings, maps, and sets. These methods help validate collection states and ensure non-empty collections for safe operations.

3

4

## Capabilities

5

6

### Array Emptiness Checking

7

8

Check if arrays are empty or contain items.

9

10

```typescript { .api }

11

/**

12

* Check if value is an empty array

13

* @param value - Value to check

14

* @returns True if value is empty array

15

*/

16

function isEmptyArray(value: unknown): value is never[];

17

18

/**

19

* Check if value is a non-empty array

20

* @param value - Value to check

21

* @returns True if value is non-empty array

22

*/

23

function isNonEmptyArray<T = unknown, Item = unknown>(value: T | Item[]): value is [Item, ...Item[]];

24

```

25

26

**Usage Examples:**

27

28

```typescript

29

import is from '@sindresorhus/is';

30

31

is.emptyArray([]); // => true

32

is.emptyArray([1, 2, 3]); // => false

33

is.emptyArray('not array'); // => false

34

35

is.nonEmptyArray([1, 2, 3]); // => true

36

is.nonEmptyArray([]); // => false

37

38

// Type guard usage

39

function processArray(arr: unknown) {

40

if (is.nonEmptyArray(arr)) {

41

// arr is now typed as [unknown, ...unknown[]]

42

console.log('First item:', arr[0]);

43

console.log('Length:', arr.length); // guaranteed > 0

44

}

45

}

46

```

47

48

### Object Emptiness Checking

49

50

Check if objects have enumerable properties.

51

52

```typescript { .api }

53

/**

54

* Check if value is an empty object (no enumerable properties)

55

* @param value - Value to check

56

* @returns True if value is empty object

57

*/

58

function isEmptyObject<Key extends keyof any = string>(value: unknown): value is Record<Key, never>;

59

60

/**

61

* Check if value is a non-empty object (has enumerable properties)

62

* @param value - Value to check

63

* @returns True if value is non-empty object

64

*/

65

function isNonEmptyObject<Key extends keyof any = string, Value = unknown>(value: unknown): value is Record<Key, Value>;

66

```

67

68

**Usage Examples:**

69

70

```typescript

71

import is from '@sindresorhus/is';

72

73

is.emptyObject({}); // => true

74

is.emptyObject({a: 1}); // => false

75

is.emptyObject([]); // => false (arrays are not plain objects)

76

is.emptyObject(new Map()); // => false (Maps are not plain objects)

77

78

is.nonEmptyObject({a: 1}); // => true

79

is.nonEmptyObject({}); // => false

80

81

// Note: Only checks enumerable properties

82

const obj = {};

83

Object.defineProperty(obj, 'hidden', {

84

value: 42,

85

enumerable: false

86

});

87

is.emptyObject(obj); // => true (hidden property is not enumerable)

88

```

89

90

### Map Emptiness Checking

91

92

Check if Map objects are empty or contain entries.

93

94

```typescript { .api }

95

/**

96

* Check if value is an empty Map

97

* @param value - Value to check

98

* @returns True if value is empty Map

99

*/

100

function isEmptyMap(value: unknown): value is Map<never, never>;

101

102

/**

103

* Check if value is a non-empty Map

104

* @param value - Value to check

105

* @returns True if value is non-empty Map

106

*/

107

function isNonEmptyMap<Key = unknown, Value = unknown>(value: unknown): value is Map<Key, Value>;

108

```

109

110

**Usage Examples:**

111

112

```typescript

113

import is from '@sindresorhus/is';

114

115

const emptyMap = new Map();

116

const mapWithItems = new Map([['key', 'value']]);

117

118

is.emptyMap(emptyMap); // => true

119

is.emptyMap(mapWithItems); // => false

120

is.emptyMap({}); // => false

121

122

is.nonEmptyMap(mapWithItems); // => true

123

is.nonEmptyMap(emptyMap); // => false

124

125

// Type guard usage

126

function processMap(map: unknown) {

127

if (is.nonEmptyMap(map)) {

128

// map is now typed as Map<unknown, unknown> with size > 0

129

console.log('Map size:', map.size);

130

for (const [key, value] of map) {

131

console.log(key, value);

132

}

133

}

134

}

135

```

136

137

### Set Emptiness Checking

138

139

Check if Set objects are empty or contain values.

140

141

```typescript { .api }

142

/**

143

* Check if value is an empty Set

144

* @param value - Value to check

145

* @returns True if value is empty Set

146

*/

147

function isEmptySet(value: unknown): value is Set<never>;

148

149

/**

150

* Check if value is a non-empty Set

151

* @param value - Value to check

152

* @returns True if value is non-empty Set

153

*/

154

function isNonEmptySet<T = unknown>(value: unknown): value is Set<T>;

155

```

156

157

**Usage Examples:**

158

159

```typescript

160

import is from '@sindresorhus/is';

161

162

const emptySet = new Set();

163

const setWithItems = new Set([1, 2, 3]);

164

165

is.emptySet(emptySet); // => true

166

is.emptySet(setWithItems); // => false

167

is.emptySet([]); // => false

168

169

is.nonEmptySet(setWithItems); // => true

170

is.nonEmptySet(emptySet); // => false

171

172

// Type guard usage

173

function processSet(set: unknown) {

174

if (is.nonEmptySet(set)) {

175

// set is now typed as Set<unknown> with size > 0

176

console.log('Set size:', set.size);

177

for (const value of set) {

178

console.log(value);

179

}

180

}

181

}

182

```

183

184

### Array-like Type Checking

185

186

Check if a value is array-like (has a length property and indexed access).

187

188

```typescript { .api }

189

/**

190

* Check if value is array-like (has length property)

191

* @param value - Value to check

192

* @returns True if value is array-like

193

*/

194

function isArrayLike<T = unknown>(value: unknown): value is ArrayLike<T>;

195

196

type ArrayLike<T> = {

197

readonly [index: number]: T;

198

readonly length: number;

199

};

200

```

201

202

**Usage Examples:**

203

204

```typescript

205

import is from '@sindresorhus/is';

206

207

is.arrayLike([]); // => true

208

is.arrayLike('hello'); // => true (strings are array-like)

209

is.arrayLike({0: 'a', 1: 'b', length: 2}); // => true

210

is.arrayLike(document.querySelectorAll('div')); // => true (NodeList)

211

212

function processArguments() {

213

is.arrayLike(arguments); // => true

214

}

215

216

is.arrayLike({}); // => false

217

is.arrayLike(() => {}); // => false

218

```

219

220

### Tuple-like Type Checking

221

222

Check if a value matches a tuple structure with type guards.

223

224

```typescript { .api }

225

/**

226

* Check if value matches tuple structure with guards

227

* @param value - Value to check

228

* @param guards - Array of type guard functions

229

* @returns True if value matches tuple structure

230

*/

231

function isTupleLike<T extends Array<TypeGuard<unknown>>>(

232

value: unknown,

233

guards: [...T]

234

): value is ResolveTypesOfTypeGuardsTuple<T>;

235

236

type TypeGuard<T> = (value: unknown) => value is T;

237

```

238

239

**Usage Examples:**

240

241

```typescript

242

import is from '@sindresorhus/is';

243

244

// Check for [string, number] tuple

245

const guards = [is.string, is.number] as const;

246

is.tupleLike(['hello', 42], guards); // => true

247

is.tupleLike(['hello', 'world'], guards); // => false

248

is.tupleLike(['hello'], guards); // => false (wrong length)

249

250

// Type guard usage

251

function processTuple(value: unknown) {

252

if (is.tupleLike(value, [is.string, is.number, is.boolean])) {

253

// value is now typed as [string, number, boolean]

254

const [str, num, bool] = value;

255

console.log(str.toUpperCase(), num * 2, !bool);

256

}

257

}

258

259

// More complex example

260

const complexGuards = [

261

is.string,

262

(v: unknown): v is {id: number} => is.plainObject(v) && is.number((v as any).id)

263

] as const;

264

265

if (is.tupleLike(someValue, complexGuards)) {

266

// someValue is typed as [string, {id: number}]

267

console.log(someValue[0].length, someValue[1].id);

268

}

269

```

270

271

### Valid Length Checking

272

273

Check if a value is a valid length (safe integer >= 0).

274

275

```typescript { .api }

276

/**

277

* Check if value is a valid length (safe integer >= 0)

278

* @param value - Value to check

279

* @returns True if value is valid length

280

*/

281

function isValidLength(value: unknown): value is number;

282

```

283

284

**Usage Examples:**

285

286

```typescript

287

import is from '@sindresorhus/is';

288

289

is.validLength(0); // => true

290

is.validLength(5); // => true

291

is.validLength(Number.MAX_SAFE_INTEGER); // => true

292

is.validLength(-1); // => false

293

is.validLength(1.5); // => false

294

is.validLength(Number.MAX_SAFE_INTEGER + 1); // => false

295

is.validLength('5'); // => false

296

297

// Useful for validating array-like objects

298

function createArrayLike(length: unknown) {

299

if (is.validLength(length)) {

300

// length is now typed as number and guaranteed to be valid

301

const obj: any = {};

302

obj.length = length;

303

for (let i = 0; i < length; i++) {

304

obj[i] = i;

305

}

306

return obj;

307

}

308

throw new Error('Invalid length');

309

}

310

```

311

312

## Notes

313

314

- Empty/non-empty object checks only consider enumerable properties using `Object.keys()`

315

- Non-enumerable properties are ignored in object emptiness checks

316

- Array-like includes strings, NodeLists, arguments objects, and any object with numeric indices and length

317

- Tuple-like checking validates both length and type of each element

318

- Valid length is useful for creating array-like objects and validating counts

319

- All collection checks work with TypeScript type guards for compile-time type narrowing