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

assertions.mddocs/

0

# Assertions

1

2

Error-throwing assertion methods corresponding to all type checking functions, with optional custom error messages. Assertions provide runtime type validation that throws `TypeError` when checks fail.

3

4

## Capabilities

5

6

### Assertion Object

7

8

The `assert` object contains assertion methods for all type checking functions.

9

10

```typescript { .api }

11

/**

12

* Assertion methods that throw TypeError if type check fails

13

*/

14

const assert: Assert;

15

16

interface Assert {

17

// Basic type assertions

18

undefined: (value: unknown, message?: string) => asserts value is undefined;

19

string: (value: unknown, message?: string) => asserts value is string;

20

number: (value: unknown, message?: string) => asserts value is number;

21

boolean: (value: unknown, message?: string) => asserts value is boolean;

22

symbol: (value: unknown, message?: string) => asserts value is symbol;

23

bigint: (value: unknown, message?: string) => asserts value is bigint;

24

null: (value: unknown, message?: string) => asserts value is null;

25

26

// Object type assertions

27

array: <T = unknown>(value: unknown, assertion?: (element: unknown) => asserts element is T, message?: string) => asserts value is T[];

28

object: (value: unknown, message?: string) => asserts value is object;

29

function: (value: unknown, message?: string) => asserts value is Function;

30

date: (value: unknown, message?: string) => asserts value is Date;

31

regExp: (value: unknown, message?: string) => asserts value is RegExp;

32

33

// Multi-value assertions

34

all: (predicate: Predicate, ...values: unknown[]) => void | never;

35

any: (predicate: Predicate | Predicate[], ...values: unknown[]) => void | never;

36

}

37

38

type Predicate = (value: unknown) => boolean;

39

```

40

41

### Basic Type Assertions

42

43

Assert primitive and basic types with automatic error throwing.

44

45

**Usage Examples:**

46

47

```typescript

48

import { assert } from '@sindresorhus/is';

49

50

// Basic assertions

51

assert.string('hello'); // passes

52

assert.string(42); // throws TypeError

53

54

assert.number(42); // passes

55

assert.number('42'); // throws TypeError

56

57

// Custom error messages

58

assert.string(someValue, 'User name must be a string');

59

assert.number(config.port, 'Port must be a number');

60

61

// Type narrowing

62

function processUserInput(name: unknown, age: unknown) {

63

assert.string(name); // name is now typed as string

64

assert.number(age); // age is now typed as number

65

66

return {

67

name: name.toUpperCase(),

68

age: age + 1

69

};

70

}

71

```

72

73

### Array Assertions

74

75

Assert arrays with optional item validation.

76

77

```typescript { .api }

78

/**

79

* Assert value is array, optionally validating all items

80

* @param value - Value to assert

81

* @param assertion - Optional assertion for each array item

82

* @param message - Optional custom error message

83

*/

84

function assertArray<T = unknown>(

85

value: unknown,

86

assertion?: (element: unknown, message?: string) => asserts element is T,

87

message?: string

88

): asserts value is T[];

89

```

90

91

**Usage Examples:**

92

93

```typescript

94

import { assert } from '@sindresorhus/is';

95

96

// Basic array assertion

97

assert.array([1, 2, 3]); // passes

98

assert.array('not array'); // throws TypeError

99

100

// Array with item validation

101

assert.array([1, 2, 3], assert.number); // passes

102

assert.array([1, '2', 3], assert.number); // throws (string item)

103

104

// Type narrowing with validation

105

function processNumbers(data: unknown) {

106

assert.array(data, assert.number, 'Data must be array of numbers');

107

// data is now typed as number[]

108

109

return data.map(n => n * 2);

110

}

111

112

// Custom validation

113

function assertStringArray(value: unknown): asserts value is string[] {

114

assert.array(value, assert.string, 'Must be array of strings');

115

}

116

```

117

118

### Multi-value Assertions

119

120

Assert conditions across multiple values.

121

122

```typescript { .api }

123

/**

124

* Assert all values pass predicate

125

* @param predicate - Function to test each value

126

* @param values - Values to test

127

* @throws TypeError if any value fails

128

*/

129

function assertAll(predicate: Predicate, ...values: unknown[]): void | never;

130

131

/**

132

* Assert any value passes any predicate

133

* @param predicate - Single predicate or array of predicates

134

* @param values - Values to test

135

* @throws TypeError if no value passes any predicate

136

*/

137

function assertAny(predicate: Predicate | Predicate[], ...values: unknown[]): void | never;

138

```

139

140

**Usage Examples:**

141

142

```typescript

143

import { assert } from '@sindresorhus/is';

144

import is from '@sindresorhus/is';

145

146

// Assert all values match predicate

147

assert.all(is.string, 'hello', 'world'); // passes

148

assert.all(is.string, 'hello', 42); // throws

149

150

// Assert any value matches predicate

151

assert.any(is.string, 42, true, 'hello'); // passes (string found)

152

assert.any(is.string, 42, true, null); // throws (no strings)

153

154

// Multiple predicates

155

assert.any([is.string, is.number], 'hello', {}, []); // passes (string found)

156

157

// Function validation

158

function processUserData(name: unknown, email: unknown, phone: unknown) {

159

assert.all(is.string, name, email, phone);

160

// All are now typed as string

161

162

return {

163

name: name.trim(),

164

email: email.toLowerCase(),

165

phone: phone.replace(/\D/g, '')

166

};

167

}

168

169

function requireSomeContact(email: unknown, phone: unknown, address: unknown) {

170

assert.any(is.string, email, phone, address);

171

// At least one contact method is provided

172

}

173

```

174

175

## Usage Patterns

176

177

### API Input Validation

178

179

```typescript

180

import { assert } from '@sindresorhus/is';

181

import is from '@sindresorhus/is';

182

183

interface User {

184

id: number;

185

name: string;

186

email: string;

187

age: number;

188

isActive: boolean;

189

}

190

191

function createUser(data: unknown): User {

192

assert.object(data, 'User data must be an object');

193

194

const userData = data as Record<string, unknown>;

195

196

assert.number(userData.id, 'User ID must be a number');

197

assert.string(userData.name, 'Name must be a string');

198

assert.string(userData.email, 'Email must be a string');

199

assert.number(userData.age, 'Age must be a number');

200

assert.boolean(userData.isActive, 'isActive must be a boolean');

201

202

// Additional validation

203

if (!is.positiveNumber(userData.age)) {

204

throw new Error('Age must be positive');

205

}

206

207

if (!userData.email.includes('@')) {

208

throw new Error('Email must be valid');

209

}

210

211

return userData as User;

212

}

213

```

214

215

### Configuration Validation

216

217

```typescript

218

import { assert } from '@sindresorhus/is';

219

import is from '@sindresorhus/is';

220

221

interface DatabaseConfig {

222

host: string;

223

port: number;

224

database: string;

225

credentials: {

226

username: string;

227

password: string;

228

};

229

ssl: boolean;

230

poolSize: number;

231

}

232

233

function validateDatabaseConfig(config: unknown): DatabaseConfig {

234

assert.object(config, 'Database config must be an object');

235

236

const cfg = config as Record<string, unknown>;

237

238

// Basic type assertions

239

assert.string(cfg.host, 'Database host must be a string');

240

assert.number(cfg.port, 'Database port must be a number');

241

assert.string(cfg.database, 'Database name must be a string');

242

assert.boolean(cfg.ssl, 'SSL setting must be a boolean');

243

assert.number(cfg.poolSize, 'Pool size must be a number');

244

245

// Nested object validation

246

assert.object(cfg.credentials, 'Credentials must be an object');

247

const creds = cfg.credentials as Record<string, unknown>;

248

249

assert.all(is.string, creds.username, creds.password);

250

251

// Range validation

252

if (!is.inRange(cfg.port as number, [1, 65535])) {

253

throw new Error('Port must be between 1 and 65535');

254

}

255

256

if (!is.positiveNumber(cfg.poolSize as number)) {

257

throw new Error('Pool size must be positive');

258

}

259

260

return cfg as DatabaseConfig;

261

}

262

```

263

264

### Type-safe Data Processing

265

266

```typescript

267

import { assert } from '@sindresorhus/is';

268

import is from '@sindresorhus/is';

269

270

function processApiResponse(response: unknown) {

271

assert.object(response, 'API response must be an object');

272

273

const data = response as Record<string, unknown>;

274

275

assert.array(data.items, 'Response must contain items array');

276

277

// Process each item

278

const processedItems = (data.items as unknown[]).map((item, index) => {

279

assert.object(item, `Item ${index} must be an object`);

280

281

const itemData = item as Record<string, unknown>;

282

283

assert.string(itemData.id, `Item ${index} must have string ID`);

284

assert.string(itemData.name, `Item ${index} must have string name`);

285

286

// Optional fields

287

if (itemData.description !== undefined) {

288

assert.string(itemData.description, `Item ${index} description must be string`);

289

}

290

291

return {

292

id: itemData.id,

293

name: itemData.name,

294

description: itemData.description as string | undefined

295

};

296

});

297

298

return processedItems;

299

}

300

```

301

302

### Form Data Validation

303

304

```typescript

305

import { assert } from '@sindresorhus/is';

306

import is from '@sindresorhus/is';

307

308

interface ContactForm {

309

name: string;

310

email: string;

311

subject: string;

312

message: string;

313

subscribe: boolean;

314

}

315

316

function validateContactForm(formData: unknown): ContactForm {

317

assert.object(formData, 'Form data is required');

318

319

const data = formData as Record<string, unknown>;

320

321

// Required string fields

322

const requiredFields = ['name', 'email', 'subject', 'message'];

323

assert.all(is.string, ...requiredFields.map(field => data[field]));

324

325

// Additional validations

326

const form = data as Partial<ContactForm>;

327

328

if (!is.nonEmptyStringAndNotWhitespace(form.name)) {

329

throw new Error('Name cannot be empty');

330

}

331

332

if (!form.email?.includes('@')) {

333

throw new Error('Email must be valid');

334

}

335

336

if (!is.nonEmptyStringAndNotWhitespace(form.subject)) {

337

throw new Error('Subject is required');

338

}

339

340

if (!is.nonEmptyStringAndNotWhitespace(form.message)) {

341

throw new Error('Message is required');

342

}

343

344

// Optional boolean field

345

const subscribe = data.subscribe !== undefined ?

346

(assert.boolean(data.subscribe), data.subscribe) : false;

347

348

return {

349

name: form.name!,

350

email: form.email!,

351

subject: form.subject!,

352

message: form.message!,

353

subscribe

354

};

355

}

356

```

357

358

### Error Handling Patterns

359

360

```typescript

361

import { assert } from '@sindresorhus/is';

362

363

// Custom assertion wrapper

364

function assertWithContext<T>(

365

value: unknown,

366

assertion: (value: unknown, message?: string) => asserts value is T,

367

context: string

368

): asserts value is T {

369

try {

370

assertion(value);

371

} catch (error) {

372

throw new Error(`${context}: ${error.message}`);

373

}

374

}

375

376

// Usage

377

function processUser(userData: unknown, userId: string) {

378

assertWithContext(userData, assert.object, `User ${userId}`);

379

380

const user = userData as Record<string, unknown>;

381

382

assertWithContext(user.name, assert.string, `User ${userId} name`);

383

assertWithContext(user.age, assert.number, `User ${userId} age`);

384

}

385

386

// Batch validation with detailed errors

387

function validateBatch<T>(

388

items: unknown[],

389

assertion: (value: unknown, message?: string) => asserts value is T,

390

itemName: string

391

): T[] {

392

return items.map((item, index) => {

393

try {

394

assertion(item, `${itemName} at index ${index} is invalid`);

395

return item;

396

} catch (error) {

397

throw new Error(`Validation failed for ${itemName}[${index}]: ${error.message}`);

398

}

399

});

400

}

401

```

402

403

## Error Messages

404

405

### Default Error Messages

406

407

When assertions fail, they throw `TypeError` with descriptive messages:

408

409

```typescript

410

// Default error format

411

assert.string(42);

412

// TypeError: Expected value which is `string`, received value of type `number`.

413

414

assert.array('not array');

415

// TypeError: Expected value which is `Array`, received value of type `string`.

416

```

417

418

### Custom Error Messages

419

420

All assertion methods (except `assertAll` and `assertAny`) support custom error messages:

421

422

```typescript

423

import { assert } from '@sindresorhus/is';

424

425

assert.string(42, 'Username must be a string');

426

// TypeError: Username must be a string

427

428

assert.number(config.port, 'Configuration port must be a number');

429

// TypeError: Configuration port must be a number

430

431

assert.array(data, assert.string, 'Expected array of strings');

432

// TypeError: Expected array of strings

433

```

434

435

## Notes

436

437

- All assertion methods throw `TypeError` on failure, never return values

438

- Assertions provide TypeScript type narrowing after successful validation

439

- Custom error messages are recommended for user-facing validation

440

- `assertAll` and `assertAny` do not support custom messages

441

- Assertions are ideal for input validation, API boundaries, and configuration parsing

442

- Use assertions early in functions to establish type safety for the rest of the function

443

- Assertion failures should be caught and handled appropriately in production code