npm package: @oxog/isnumber
Description: A strict, fast, zero-dependency utility for checking JavaScript numbers
Author: Ersin Koc
Latest version: 1.0.2

# @oxog/isnumber

> A strict, fast, zero-dependency utility for checking JavaScript numbers

[![npm version](https://img.shields.io/npm/v/@oxog/isnumber.svg)](https://www.npmjs.com/package/@oxog/isnumber)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
[![Zero Dependencies](https://img.shields.io/badge/Dependencies-0-green.svg)](https://www.npmjs.com/package/@oxog/isnumber?activeTab=dependencies)

## Installation

```bash
npm install @oxog/isnumber
```

```bash
yarn add @oxog/isnumber
```

```bash
pnpm add @oxog/isnumber
```

## Usage

```typescript
import { isNumber, isNumberStrict, isNumberLoose } from '@oxog/isnumber';

// Default behavior (strict)
isNumber(5);              // true
isNumber('5');            // false
isNumber(new Number(5));  // false
isNumber(NaN);            // false
isNumber(Infinity);       // false

// With options
isNumber('5', { allowCoercion: true });           // true
isNumber(new Number(5), { allowBoxed: true });    // true

// Convenience functions
isNumberStrict(5);        // true - only primitive finite numbers
isNumberLoose('5');       // true - allows boxed and coercible values
```

## API

### `isNumber(value: unknown, options?: Options): boolean`

The main function that checks if a value is a finite number.

#### Options

```typescript
interface Options {
  allowBoxed?: boolean;     // Allow boxed numbers like new Number(5) (default: false)
  allowCoercion?: boolean;  // Allow numeric strings like '5', '3.14' (default: false)
}
```

### `isNumberStrict(value: unknown): boolean`

Equivalent to `isNumber(value)` with no options. Only accepts primitive finite numbers.

### `isNumberLoose(value: unknown): boolean`

Equivalent to `isNumber(value, { allowBoxed: true, allowCoercion: true })`. Accepts all reasonable number representations.

## Examples

### Basic Usage

```typescript
// Primitive numbers
isNumber(42);             // true
isNumber(3.14);           // true
isNumber(-0);             // true
isNumber(0);              // true

// Non-finite values
isNumber(NaN);            // false
isNumber(Infinity);       // false
isNumber(-Infinity);      // false

// Non-numbers
isNumber('42');           // false
isNumber(true);           // false
isNumber(null);           // false
isNumber(undefined);      // false
isNumber({});             // false
isNumber([]);             // false
```

### With Coercion

```typescript
const options = { allowCoercion: true };

isNumber('42', options);      // true
isNumber('3.14', options);    // true
isNumber('1e10', options);    // true
isNumber(' 5 ', options);     // true (trimmed)
isNumber('', options);        // false
isNumber('abc', options);     // false
isNumber('NaN', options);     // false
isNumber('Infinity', options); // false
```

### With Boxed Numbers

```typescript
const options = { allowBoxed: true };

isNumber(new Number(42), options);       // true
isNumber(new Number(0), options);        // true
isNumber(new Number(NaN), options);      // false
isNumber(new Number(Infinity), options); // false
```

## Comparison with Other Libraries

| Feature | @oxog/isnumber | lodash.isNumber | is-number |
|---------|----------------|-----------------|-----------|
| Zero dependencies | ✅ | ❌ | ✅ |
| TypeScript support | ✅ | ✅ | ❌ |
| Strict by default | ✅ | ❌ | ❌ |
| Configurable | ✅ | ❌ | ❌ |
| Tree-shakeable | ✅ | ❌ | ✅ |
| Size (minified) | ~300B | ~1KB | ~400B |

### Behavioral Differences

```typescript
// @oxog/isnumber (strict by default)
isNumber('5');            // false
isNumber(new Number(5));  // false

// lodash.isNumber
_.isNumber('5');          // false
_.isNumber(new Number(5)); // true

// is-number (npm)
isNumber('5');            // true
isNumber(new Number(5));  // false
```

## Performance

Based on our benchmarks, `@oxog/isnumber` performs comparably or better than popular alternatives:

- **Primitive numbers**: ~2-3x faster than lodash
- **String validation**: On par with is-number
- **Overall**: 10-20% faster in mixed scenarios

Run benchmarks locally:

```bash
npm run benchmark
```

## TypeScript

Full TypeScript support with strict typing:

```typescript
import { isNumber, type Options } from '@oxog/isnumber';

const options: Options = {
  allowBoxed: true,
  allowCoercion: false
};

function processValue(value: unknown): number | null {
  if (isNumber(value, options)) {
    // TypeScript knows value is number-like
    return Number(value);
  }
  return null;
}
```

## Use Cases

### Form Validation

```typescript
function validateAge(input: unknown): boolean {
  return isNumber(input, { allowCoercion: true }) && 
         Number(input) >= 0 && 
         Number(input) <= 150;
}
```

### API Response Parsing

```typescript
function parseApiResponse(data: unknown): number[] {
  if (!Array.isArray(data)) return [];
  
  return data
    .filter(item => isNumber(item, { allowCoercion: true }))
    .map(Number);
}
```

### Configuration Validation

```typescript
function validateConfig(config: Record<string, unknown>) {
  const errors: string[] = [];
  
  if (!isNumber(config.port, { allowCoercion: true })) {
    errors.push('Port must be a number');
  }
  
  if (!isNumber(config.timeout)) {
    errors.push('Timeout must be a number in milliseconds');
  }
  
  return errors;
}
```

## Contributing

We welcome contributions! Please see our [Contributing Guide](https://github.com/ersinkoc/isnumber/blob/main/CONTRIBUTING.md) for details.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

MIT © [Ersin Koc](https://github.com/ersinkoc)

---

Made with ❤️ by the OXOG team