JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 67
  • Score
    100M100P100Q65553F
  • License MIT

A modern TypeScript replacement for 'isarray' with 12+ enhanced array validation utilities and zero dependencies

Package Exports

  • js-isarray

Readme

js-isarray

A modern TypeScript-first array validation library with 12+ powerful validators and zero dependencies.

npm version License: MIT TypeScript Buy Me A Coffee

๐Ÿ”„ Migrating from isarray

Perfect drop-in replacement for the popular isarray package (118M weekly downloads)!

# Simply replace isarray with js-isarray
npm uninstall isarray
npm install js-isarray

Zero code changes needed! Your existing code works exactly the same:

// Before (using isarray)
var isArray = require("isarray");
console.log(isArray([])); // => true
console.log(isArray({})); // => false

// After (using js-isarray) - SAME CODE!
var isArray = require("js-isarray");
console.log(isArray([])); // => true
console.log(isArray({})); // => false

Plus you get these bonuses for free:

// ๐ŸŽ‰ Modern ES6/TypeScript imports work too
import isArray from "js-isarray";

// ๐Ÿš€ 11+ additional validators
import { isStringArray, isNumberArray, validateArray } from "js-isarray";

isStringArray(["hello", "world"]); // true
isNumberArray([1, 2, 3]); // true
validateArray([1, 2], { minLength: 2, elementType: "number" }); // true

// ๐ŸŽฏ Full TypeScript support (no @types needed!)
function processData(data: unknown) {
  if (isArray(data)) {
    // TypeScript knows 'data' is an array here โœจ
    return data.length;
  }
}

Why js-isarray?

  • ๐Ÿš€ Drop-in replacement for the classic isarray package
  • ๐ŸŽฏ TypeScript-first with proper type guards
  • ๐Ÿ”ง 12+ validators beyond basic isArray()
  • ๐Ÿ“ฆ Tiny footprint - only 8.9KB, zero dependencies
  • โœจ Modern tooling - ESM, CommonJS, and full TypeScript support

๐Ÿš€ Quick Start

npm install js-isarray
import { isArray, isStringArray, validateArray } from "js-isarray";

// Basic (backwards compatible with is-array)
isArray([1, 2, 3]); // true

// Type-specific validation
isStringArray(["hello", "world"]); // true
isStringArray(["hello", 123]); // false

// Complex validation
validateArray([1, 2, 3], {
  minLength: 2,
  maxLength: 5,
  elementType: "number",
}); // true

โœจ Features

  • ๐Ÿ”ง 12+ validators - isStringArray, isNumberArray, validateArray, etc.
  • ๐ŸŽฏ TypeScript-first - Built-in type guards, no @types needed
  • ๐Ÿ“ฆ Universal - Works in Node.js, browsers, React, Vue, Angular
  • โšก Lightweight - 8.9KB gzipped, zero dependencies
  • ๐Ÿ”„ Compatible - Drop-in replacement for isarray

Installation

npm install js-isarray
yarn add js-isarray
pnpm add js-isarray

Quick Start

import { isArray, isStringArray, validateArray } from "js-isarray";

// Basic array checking (backwards compatible)
isArray([1, 2, 3]); // true
isArray("not array"); // false

// Type-specific validation
isStringArray(["hello", "world"]); // true
isStringArray(["hello", 123]); // false

// Advanced validation
validateArray([1, 2, 3], {
  minLength: 2,
  maxLength: 5,
  elementType: "number",
}); // true

API Reference

๐Ÿ” Basic Array Validation

isArray<T>(value: unknown): value is T[]

The classic array checker - Works exactly like Array.isArray() but with TypeScript support.

import { isArray } from "js-isarray";

// Basic usage
isArray([]); // true
isArray([1, 2, 3]); // true
isArray("string"); // false
isArray(null); // false

// TypeScript type narrowing
function processArray(data: unknown) {
  if (isArray(data)) {
    // TypeScript now knows 'data' is an array
    return data.length; // โœ… No TypeScript errors
  }
}

isNonEmptyArray<T>(value: unknown): value is [T, ...T[]]

Ensures array has at least one element - Perfect for validation where empty arrays aren't allowed.

import { isNonEmptyArray } from "js-isarray";

// Validation examples
isNonEmptyArray([1, 2, 3]); // true
isNonEmptyArray(["hello"]); // true
isNonEmptyArray([]); // false

// Real-world usage
function getFirstItem(list: unknown) {
  if (isNonEmptyArray(list)) {
    return list[0]; // โœ… Safe - TypeScript knows it exists
  }
  throw new Error("List cannot be empty");
}

isEmptyArray(value: unknown): value is []

Checks for empty arrays - Useful for initialization checks.

import { isEmptyArray } from "js-isarray";

isEmptyArray([]); // true
isEmptyArray([1]); // false
isEmptyArray(null); // false

// Usage example
function initializeIfEmpty(data: unknown) {
  if (isEmptyArray(data)) {
    return ["default", "values"];
  }
  return data;
}

๐ŸŽฏ Type-Specific Validation

isStringArray(value: unknown): value is string[]

Validates arrays of strings - Perfect for form data, user inputs, or configuration.

import { isStringArray } from "js-isarray";

// Basic validation
isStringArray(["hello", "world"]); // true
isStringArray(["hello", 123]); // false
isStringArray([]); // true (empty arrays pass)

// Real-world example: Form validation
function validateTags(input: unknown): string[] {
  if (isStringArray(input) && input.every((tag) => tag.length > 0)) {
    return input; // โœ… TypeScript knows this is string[]
  }
  throw new Error("Tags must be an array of non-empty strings");
}

isNumberArray(value: unknown): value is number[]

Validates arrays of numbers - Excludes NaN values for data integrity.

import { isNumberArray } from "js-isarray";

// Basic validation
isNumberArray([1, 2, 3.14]); // true
isNumberArray([1, NaN, 3]); // false (NaN is excluded!)
isNumberArray(["1", 2]); // false

// Real-world example: Coordinates validation
function processCoordinates(coords: unknown) {
  if (isNumberArray(coords) && coords.length === 2) {
    const [x, y] = coords; // โœ… TypeScript knows these are numbers
    return { x, y };
  }
  throw new Error("Coordinates must be [x, y] numbers");
}

isBooleanArray(value: unknown): value is boolean[]

Validates arrays of booleans - Great for feature flags or checkbox states.

import { isBooleanArray } from "js-isarray";

isBooleanArray([true, false, true]); // true
isBooleanArray([true, 1, false]); // false
isBooleanArray([]); // true

// Real-world example: Feature flags
function applyFeatureFlags(flags: unknown) {
  if (isBooleanArray(flags)) {
    return flags.map((enabled, index) => ({
      [`feature_${index}`]: enabled,
    }));
  }
  return {};
}

isObjectArray(value: unknown): value is Record<string, unknown>[]

Validates arrays of objects - Excludes null and nested arrays.

import { isObjectArray } from "js-isarray";

isObjectArray([{}, { name: "John" }]); // true
isObjectArray([{}, null]); // false
isObjectArray([{}, []]); // false

// Real-world example: API response validation
interface User {
  id: string;
  name: string;
}

function validateUsers(response: unknown): User[] {
  if (isObjectArray(response)) {
    return response.filter(
      (user): user is User =>
        typeof user.id === "string" && typeof user.name === "string"
    );
  }
  return [];
}

๐Ÿ“ Length-Based Validation

isArrayWithLength<T>(value: unknown, length: number): value is T[]

Validates exact array length - Perfect for fixed-size data structures.

import { isArrayWithLength } from "js-isarray";

isArrayWithLength([1, 2, 3], 3); // true
isArrayWithLength([1, 2], 3); // false

// Real-world example: RGB color validation
function validateRGBColor(color: unknown): [number, number, number] {
  if (isArrayWithLength(color, 3) && isNumberArray(color)) {
    const [r, g, b] = color;
    if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) {
      return color as [number, number, number];
    }
  }
  throw new Error("RGB color must be [r, g, b] with values 0-255");
}

isArrayWithMinLength<T>(value: unknown, minLength: number): value is T[]

Validates minimum array length - Ensures you have enough data to work with.

import { isArrayWithMinLength } from "js-isarray";

isArrayWithMinLength([1, 2, 3], 2); // true
isArrayWithMinLength([1], 2); // false

// Real-world example: Pagination validation
function paginateResults(data: unknown, pageSize: number = 10) {
  if (isArrayWithMinLength(data, 1)) {
    // โœ… TypeScript knows data is a non-empty array
    const pages = [];
    for (let i = 0; i < data.length; i += pageSize) {
      pages.push(data.slice(i, i + pageSize));
    }
    return pages;
  }
  return [];
}

isArrayWithMaxLength<T>(value: unknown, maxLength: number): value is T[]

Validates maximum array length - Prevents processing oversized data.

import { isArrayWithMaxLength } from "js-isarray";

isArrayWithMaxLength([1, 2], 3); // true
isArrayWithMaxLength([1, 2, 3, 4], 3); // false

// Real-world example: Form validation
function validateChoices(selections: unknown, maxChoices: number) {
  if (
    isArrayWithMaxLength(selections, maxChoices) &&
    isStringArray(selections)
  ) {
    return selections; // โœ… Valid selections
  }
  throw new Error(`Please select at most ${maxChoices} options`);
}

๐Ÿ”ง Advanced Validation

isArrayOf<T>(value: unknown, typeGuard: (item: unknown) => item is T): value is T[]

The most powerful validator - Create custom type guards for complex validation.

import { isArrayOf } from "js-isarray";

// Custom type guards
const isPositiveNumber = (x: unknown): x is number =>
  typeof x === "number" && x > 0;

const isEmail = (x: unknown): x is string =>
  typeof x === "string" && /\S+@\S+\.\S+/.test(x);

// Usage examples
isArrayOf([1, 2, 3], isPositiveNumber); // true
isArrayOf([1, -2, 3], isPositiveNumber); // false

isArrayOf(["user@example.com", "admin@site.org"], isEmail); // true
isArrayOf(["not-an-email", "user@example.com"], isEmail); // false

// Real-world example: API validation
interface Product {
  id: number;
  name: string;
  price: number;
}

const isProduct = (item: unknown): item is Product => {
  return (
    typeof item === "object" &&
    item !== null &&
    typeof (item as any).id === "number" &&
    typeof (item as any).name === "string" &&
    typeof (item as any).price === "number" &&
    (item as any).price >= 0
  );
};

function validateProducts(data: unknown): Product[] {
  if (isArrayOf(data, isProduct)) {
    return data; // โœ… TypeScript knows this is Product[]
  }
  throw new Error("Invalid product data");
}

validateArray(value: unknown, options?: ArrayValidationOptions): boolean

All-in-one validator - Combine multiple validation rules in one function.

import { validateArray } from "js-isarray";

interface ArrayValidationOptions {
  allowEmpty?: boolean;
  minLength?: number;
  maxLength?: number;
  elementType?: "string" | "number" | "boolean" | "object";
}

// Examples
validateArray(["hello", "world"], {
  allowEmpty: false,
  minLength: 2,
  maxLength: 10,
  elementType: "string",
}); // true

validateArray([], { allowEmpty: false }); // false
validateArray([1, 2, 3], { elementType: "number", maxLength: 5 }); // true

// Real-world example: Form field validation
function validateFormField(fieldName: string, value: unknown) {
  const validators = {
    tags: { elementType: "string" as const, minLength: 1, maxLength: 5 },
    scores: { elementType: "number" as const, allowEmpty: false },
    features: { elementType: "boolean" as const, maxLength: 10 },
  };

  const config = validators[fieldName as keyof typeof validators];
  if (!config) return false;

  return validateArray(value, config);
}

๐Ÿ’ก Real-World Usage Examples

๐ŸŒ API Response Validation

import { isObjectArray, isStringArray, isNumberArray } from "js-isarray";

interface User {
  id: number;
  name: string;
  tags: string[];
}

async function fetchUsers(): Promise<User[]> {
  const response = await fetch("/api/users");
  const data = await response.json();

  // Validate the response structure
  if (!isObjectArray(data)) {
    throw new Error("Expected array of user objects");
  }

  return data.filter((user): user is User => {
    return (
      typeof user.id === "number" &&
      typeof user.name === "string" &&
      isStringArray(user.tags)
    );
  });
}

๐Ÿ“ Form Validation

import { validateArray, isStringArray } from "js-isarray";

interface FormData {
  categories: string[];
  ratings: number[];
  preferences: boolean[];
}

function validateForm(formData: unknown): FormData | never {
  if (typeof formData !== "object" || formData === null) {
    throw new Error("Invalid form data");
  }

  const data = formData as any;

  // Validate categories (1-5 strings, non-empty)
  if (
    !validateArray(data.categories, {
      elementType: "string",
      minLength: 1,
      maxLength: 5,
      allowEmpty: false,
    })
  ) {
    throw new Error("Categories must be 1-5 non-empty strings");
  }

  // Validate ratings (numbers between 1-10)
  if (
    !isNumberArray(data.ratings) ||
    !data.ratings.every((r: number) => r >= 1 && r <= 10)
  ) {
    throw new Error("Ratings must be numbers between 1-10");
  }

  return data as FormData;
}

โš™๏ธ Configuration Validation

import { isArrayOf, isStringArray } from "js-isarray";

interface ServerConfig {
  hosts: string[];
  ports: number[];
  middleware: string[];
}

const isValidPort = (value: unknown): value is number =>
  typeof value === "number" && value >= 1 && value <= 65535;

const isValidHost = (value: unknown): value is string =>
  typeof value === "string" && value.length > 0;

function validateConfig(config: unknown): ServerConfig {
  if (typeof config !== "object" || config === null) {
    throw new Error("Configuration must be an object");
  }

  const cfg = config as any;

  // Validate hosts
  if (!isArrayOf(cfg.hosts, isValidHost)) {
    throw new Error("Hosts must be array of non-empty strings");
  }

  // Validate ports
  if (!isArrayOf(cfg.ports, isValidPort)) {
    throw new Error("Ports must be array of valid port numbers (1-65535)");
  }

  // Validate middleware
  if (!isStringArray(cfg.middleware)) {
    throw new Error("Middleware must be array of strings");
  }

  return cfg as ServerConfig;
}

๐ŸŽจ Data Processing

import { isNonEmptyArray, isNumberArray, validateArray } from "js-isarray";

// Process coordinate arrays
function calculateDistance(coordinates: unknown): number {
  if (!isNumberArray(coordinates) || coordinates.length !== 2) {
    throw new Error("Coordinates must be [x, y] numbers");
  }

  const [x, y] = coordinates;
  return Math.sqrt(x * x + y * y);
}

// Batch processing with validation
function processDataBatch(batches: unknown[]): any[] {
  return batches
    .filter((batch) => isNonEmptyArray(batch))
    .map((batch) => {
      // Process only valid batches
      return batch.map((item) => processItem(item));
    })
    .flat();
}

// Chart data validation
interface ChartData {
  labels: string[];
  datasets: number[][];
}

function validateChartData(data: unknown): ChartData {
  if (typeof data !== "object" || data === null) {
    throw new Error("Chart data must be an object");
  }

  const chart = data as any;

  if (
    !validateArray(chart.labels, {
      elementType: "string",
      minLength: 1,
    })
  ) {
    throw new Error("Chart must have string labels");
  }

  if (
    !Array.isArray(chart.datasets) ||
    !chart.datasets.every((dataset: unknown) => isNumberArray(dataset))
  ) {
    throw new Error("Datasets must be arrays of numbers");
  }

  return chart as ChartData;
}

Backwards Compatibility

This package is designed to be a perfect drop-in replacement for the original isarray package:

// Original isarray usage
var isArray = require("isarray");

console.log(isArray([])); // => true
console.log(isArray({})); // => false

// Works exactly the same with js-isarray
var isArray = require("js-isarray");

console.log(isArray([])); // => true
console.log(isArray({})); // => false

Modern import styles also work:

// ES6 default import
import isArray from "js-isarray";

// Named imports for additional features
import { isArray, isStringArray } from "js-isarray";

TypeScript Support

Full TypeScript support with proper type guards:

function example(value: unknown) {
  if (isStringArray(value)) {
    // TypeScript automatically infers value as string[]
    value.forEach((str) => console.log(str.toUpperCase()));
  }
}

๐ŸŒ Browser & Environment Support

This package works everywhere JavaScript runs:

  • โœ… Node.js 14+
  • โœ… Modern Browsers (Chrome, Firefox, Safari, Edge)
  • โœ… React / Vue / Angular applications
  • โœ… React Native applications
  • โœ… Electron applications
  • โœ… Web Workers and Service Workers
  • โœ… Deno and Bun runtimes

Module Formats

  • ๐Ÿ“ฆ CommonJS - require('js-isarray')
  • ๐Ÿ“ฆ ES Modules - import { isArray } from 'js-isarray'
  • ๐Ÿ“ฆ TypeScript - Full type definitions included

๐Ÿ”ง Troubleshooting

Common Issues

Q: TypeScript errors about missing types

# โœ… Solution: Types are built-in, no @types package needed
# Just make sure you're importing correctly
import { isArray } from 'js-isarray';

Q: "Module not found" errors

# โœ… Solution: Check your import syntax
# Named import (recommended)
import { isArray, isStringArray } from 'js-isarray';

# Default import (backwards compatibility)
import isArray from 'js-isarray';

Q: Issues with bundlers (Webpack, Vite, etc.)

// โœ… The package provides proper module exports
// Your bundler should automatically pick the right format
// No special configuration needed

Performance Tips

  • โœ… Import only what you need: import { isArray } from 'js-isarray'
  • โœ… Use specific validators when possible: isStringArray() vs validateArray()
  • โœ… Cache type guard functions for repeated use
  • โœ… The package is lightweight (~8.9KB compressed) with zero dependencies
  • โšก Tree-shaking friendly - only bundles what you import

๐Ÿค Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

git clone https://github.com/noorjsdivs/js-isarray.git
cd js-isarray
npm install
npm test

โ˜• Support the Project

If this package has been helpful to you, consider supporting its continued development and maintenance!

Buy Me A Coffee

โ˜• Buy me a coffee - Your support helps keep this project alive and enables me to:

  • ๐Ÿ”ง Maintain and improve the package
  • ๐Ÿ› Fix bugs and add new features
  • ๐Ÿ“š Create better documentation
  • ๐Ÿ†• Develop more useful open-source tools

Every contribution, no matter how small, is greatly appreciated! ๐Ÿ’


๐Ÿ“„ License

MIT ยฉ noorjsdivs

๐Ÿ“Š Package Stats

  • ๐Ÿ“ฆ Size: ~8.9KB compressed, ~13.5KB unpacked
  • ๐Ÿ” Dependencies: Zero
  • ๐Ÿงช Tests: 28 tests, 100% coverage
  • ๐Ÿ“ TypeScript: Full type definitions included
  • ๐Ÿ—๏ธ Build: Modern tooling (Rollup + TypeScript)
  • โšก Performance: Optimized with no source maps in production

Made with โค๏ธ and TypeScript

If this package helped you, please consider giving it a โญ on GitHub!