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

numbers.mddocs/

0

# Numbers and Math

1

2

Specialized number validation including integers, safe integers, positive/negative numbers, even/odd checks, range validation, and mathematical properties.

3

4

## Capabilities

5

6

### Integer Type Checking

7

8

Check if a value is an integer or safe integer.

9

10

```typescript { .api }

11

/**

12

* Check if value is an integer

13

* @param value - Value to check

14

* @returns True if value is integer

15

*/

16

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

17

18

/**

19

* Check if value is a safe integer (within safe integer range)

20

* @param value - Value to check

21

* @returns True if value is safe integer

22

*/

23

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

24

```

25

26

**Usage Examples:**

27

28

```typescript

29

import is from '@sindresorhus/is';

30

31

is.integer(42); // => true

32

is.integer(3.14); // => false

33

is.integer(Number.MAX_VALUE); // => false (too large to be precise)

34

35

is.safeInteger(42); // => true

36

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

37

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

38

is.safeInteger(3.14); // => false

39

40

// Type guard usage

41

function processArrayIndex(index: unknown) {

42

if (is.safeInteger(index) && index >= 0) {

43

// index is now typed as number and guaranteed to be safe

44

return `Item at index ${index}`;

45

}

46

throw new Error('Invalid array index');

47

}

48

```

49

50

### Sign-based Number Checking

51

52

Check if numbers are positive or negative.

53

54

```typescript { .api }

55

/**

56

* Check if value is a positive number

57

* @param value - Value to check

58

* @returns True if value is positive number

59

*/

60

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

61

62

/**

63

* Check if value is a negative number

64

* @param value - Value to check

65

* @returns True if value is negative number

66

*/

67

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

68

```

69

70

**Usage Examples:**

71

72

```typescript

73

import is from '@sindresorhus/is';

74

75

is.positiveNumber(42); // => true

76

is.positiveNumber(0); // => false

77

is.positiveNumber(-5); // => false

78

is.positiveNumber('42'); // => false

79

80

is.negativeNumber(-42); // => true

81

is.negativeNumber(0); // => false

82

is.negativeNumber(5); // => false

83

84

// Type guard usage

85

function calculateDiscount(amount: unknown, discount: unknown) {

86

if (is.positiveNumber(amount) && is.positiveNumber(discount)) {

87

// Both are now typed as positive numbers

88

return amount - (amount * discount / 100);

89

}

90

throw new Error('Amount and discount must be positive numbers');

91

}

92

```

93

94

### Even and Odd Integer Checking

95

96

Check if integers are even or odd.

97

98

```typescript { .api }

99

/**

100

* Check if value is an even integer

101

* @param value - Value to check

102

* @returns True if value is even integer

103

*/

104

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

105

106

/**

107

* Check if value is an odd integer

108

* @param value - Value to check

109

* @returns True if value is odd integer

110

*/

111

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

112

```

113

114

**Usage Examples:**

115

116

```typescript

117

import is from '@sindresorhus/is';

118

119

is.evenInteger(2); // => true

120

is.evenInteger(3); // => false

121

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

122

is.evenInteger(2.5); // => false

123

124

is.oddInteger(3); // => true

125

is.oddInteger(2); // => false

126

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

127

128

// Type guard usage

129

function processNumbers(numbers: unknown[]) {

130

const evens = numbers.filter(is.evenInteger);

131

const odds = numbers.filter(is.oddInteger);

132

133

console.log('Even numbers:', evens);

134

console.log('Odd numbers:', odds);

135

}

136

```

137

138

### Infinity Checking

139

140

Check if a value is positive or negative infinity.

141

142

```typescript { .api }

143

/**

144

* Check if value is Infinity or -Infinity

145

* @param value - Value to check

146

* @returns True if value is infinite

147

*/

148

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

149

```

150

151

**Usage Examples:**

152

153

```typescript

154

import is from '@sindresorhus/is';

155

156

is.infinite(Infinity); // => true

157

is.infinite(-Infinity); // => true

158

is.infinite(Number.POSITIVE_INFINITY); // => true

159

is.infinite(Number.NEGATIVE_INFINITY); // => true

160

is.infinite(42); // => false

161

is.infinite(NaN); // => false

162

163

// Type guard usage

164

function safeDivision(a: number, b: number) {

165

const result = a / b;

166

if (is.infinite(result)) {

167

throw new Error('Division resulted in infinity');

168

}

169

return result;

170

}

171

```

172

173

### Range Validation

174

175

Check if a number is within a specified range.

176

177

```typescript { .api }

178

/**

179

* Check if number is within specified range

180

* @param value - Number to check

181

* @param range - Range as single number (0 to range) or [min, max] tuple

182

* @returns True if value is in range

183

*/

184

function isInRange(value: number, range: number | [number, number]): value is number;

185

```

186

187

**Usage Examples:**

188

189

```typescript

190

import is from '@sindresorhus/is';

191

192

// Single number range (0 to range)

193

is.inRange(5, 10); // => true (0 <= 5 <= 10)

194

is.inRange(-2, 10); // => false (negative values not allowed)

195

is.inRange(15, 10); // => false (above range)

196

197

// Array range [min, max]

198

is.inRange(5, [0, 10]); // => true

199

is.inRange(5, [10, 20]); // => false

200

is.inRange(15, [10, 20]); // => true

201

202

// Range order doesn't matter

203

is.inRange(5, [10, 0]); // => true (same as [0, 10])

204

205

// Type guard usage (value is already number)

206

function processScore(score: number) {

207

if (is.inRange(score, [0, 100])) {

208

// score is guaranteed to be 0-100

209

const grade = score >= 90 ? 'A' : score >= 80 ? 'B' : 'C';

210

return grade;

211

}

212

throw new Error('Score must be between 0 and 100');

213

}

214

215

// Validation with unknown input

216

function validateAge(age: unknown) {

217

if (is.number(age) && is.inRange(age, [0, 120])) {

218

return age; // Valid age

219

}

220

throw new Error('Age must be a number between 0 and 120');

221

}

222

```

223

224

### Numeric String Validation

225

226

Check if a string represents a valid number.

227

228

```typescript { .api }

229

/**

230

* Check if string represents a valid number

231

* @param value - Value to check

232

* @returns True if value is numeric string

233

*/

234

function isNumericString(value: unknown): value is `${number}`;

235

```

236

237

**Usage Examples:**

238

239

```typescript

240

import is from '@sindresorhus/is';

241

242

is.numericString('42'); // => true

243

is.numericString('3.14'); // => true

244

is.numericString('-123'); // => true

245

is.numericString('1e10'); // => true

246

is.numericString('Infinity'); // => true

247

is.numericString('-Infinity'); // => true

248

249

is.numericString('NaN'); // => false

250

is.numericString('42px'); // => false

251

is.numericString(''); // => false

252

is.numericString(' '); // => false

253

is.numericString('hello'); // => false

254

255

// Type guard usage

256

function parseNumber(input: unknown) {

257

if (is.numericString(input)) {

258

// input is now typed as `${number}`

259

const num = Number(input);

260

return num;

261

}

262

throw new Error('Input is not a numeric string');

263

}

264

265

// Form validation

266

function validateFormInput(input: unknown) {

267

if (is.string(input) && is.numericString(input)) {

268

return Number(input);

269

}

270

return null;

271

}

272

```

273

274

## Usage Patterns

275

276

### Number Validation Chain

277

278

```typescript

279

import is from '@sindresorhus/is';

280

281

function validatePositiveInteger(value: unknown): number {

282

if (!is.number(value)) {

283

throw new Error('Value must be a number');

284

}

285

286

if (!is.integer(value)) {

287

throw new Error('Value must be an integer');

288

}

289

290

if (!is.positiveNumber(value)) {

291

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

292

}

293

294

return value;

295

}

296

297

// Usage

298

try {

299

const count = validatePositiveInteger(42); // OK

300

const invalid = validatePositiveInteger(-5); // throws

301

} catch (error) {

302

console.error(error.message);

303

}

304

```

305

306

### Mathematical Operations

307

308

```typescript

309

import is from '@sindresorhus/is';

310

311

function factorial(n: unknown): number {

312

if (!is.number(n) || !is.integer(n) || !is.positiveNumber(n)) {

313

throw new Error('Factorial requires a positive integer');

314

}

315

316

if (n === 0) return 1;

317

return n * factorial(n - 1);

318

}

319

320

function gcd(a: unknown, b: unknown): number {

321

if (!is.integer(a) || !is.integer(b)) {

322

throw new Error('GCD requires integers');

323

}

324

325

const absA = Math.abs(a as number);

326

const absB = Math.abs(b as number);

327

328

return absB === 0 ? absA : gcd(absB, absA % absB);

329

}

330

```

331

332

### Range-based Processing

333

334

```typescript

335

import is from '@sindresorhus/is';

336

337

function categorizeNumbers(numbers: unknown[]): {

338

positive: number[];

339

negative: number[];

340

zero: number[];

341

invalid: unknown[];

342

} {

343

const result = {

344

positive: [] as number[],

345

negative: [] as number[],

346

zero: [] as number[],

347

invalid: [] as unknown[]

348

};

349

350

for (const num of numbers) {

351

if (!is.number(num)) {

352

result.invalid.push(num);

353

} else if (is.positiveNumber(num)) {

354

result.positive.push(num);

355

} else if (is.negativeNumber(num)) {

356

result.negative.push(num);

357

} else {

358

result.zero.push(num); // Must be 0

359

}

360

}

361

362

return result;

363

}

364

```

365

366

### Safe Math Operations

367

368

```typescript

369

import is from '@sindresorhus/is';

370

371

function safeMath(a: unknown, b: unknown, operation: string): number {

372

if (!is.number(a) || !is.number(b)) {

373

throw new Error('Both operands must be numbers');

374

}

375

376

if (!is.safeInteger(a) || !is.safeInteger(b)) {

377

throw new Error('Operands must be safe integers');

378

}

379

380

let result: number;

381

switch (operation) {

382

case '+':

383

result = a + b;

384

break;

385

case '*':

386

result = a * b;

387

break;

388

default:

389

throw new Error('Unsupported operation');

390

}

391

392

if (!is.safeInteger(result)) {

393

throw new Error('Result exceeds safe integer range');

394

}

395

396

return result;

397

}

398

```

399

400

## Notes

401

402

- `isInteger()` uses `Number.isInteger()` internally

403

- `isSafeInteger()` checks if number is within `Number.MAX_SAFE_INTEGER` range

404

- Even/odd checking only works with integers; non-integers return `false`

405

- `isInRange()` accepts the number to check as first parameter (must already be a number)

406

- Range validation with single number creates range from 0 to that number

407

- Range validation with array accepts [min, max] in any order

408

- Numeric string validation excludes `'NaN'` but includes `'Infinity'` and `'-Infinity'`

409

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