CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-sindresorhus--is

Type check values with comprehensive TypeScript type guards and runtime assertions

Pending
Overview
Eval results
Files

strings.mddocs/

Strings and Text

String-specific validation including empty strings, whitespace detection, numeric strings, URL strings, and text content validation.

Capabilities

String Emptiness Checking

Check if strings are empty or contain only whitespace.

/**
 * Check if value is an empty string
 * @param value - Value to check
 * @returns True if value is empty string
 */
function isEmptyString(value: unknown): value is '';

/**
 * Check if value is empty string or contains only whitespace
 * @param value - Value to check
 * @returns True if value is empty or whitespace string
 */
function isEmptyStringOrWhitespace(value: unknown): value is '' | Whitespace;

type Whitespace = ' '; // Represents whitespace-only strings

Usage Examples:

import is from '@sindresorhus/is';

is.emptyString(''); // => true
is.emptyString('hello'); // => false
is.emptyString(null); // => false

is.emptyStringOrWhitespace(''); // => true
is.emptyStringOrWhitespace('   '); // => true
is.emptyStringOrWhitespace('\t\n'); // => true
is.emptyStringOrWhitespace('hello'); // => false

// Type guard usage
function processInput(input: unknown) {
  if (is.string(input) && !is.emptyStringOrWhitespace(input)) {
    // input is now typed as non-empty string
    return input.trim().toUpperCase();
  }
  throw new Error('Input must be a non-empty string');
}

Non-empty String Checking

Check if strings contain content or meaningful text.

/**
 * Check if value is a non-empty string
 * @param value - Value to check
 * @returns True if value is non-empty string
 */
function isNonEmptyString(value: unknown): value is NonEmptyString;

/**
 * Check if value is non-empty string and not just whitespace
 * @param value - Value to check
 * @returns True if value is non-empty string with content
 */
function isNonEmptyStringAndNotWhitespace(value: unknown): value is NonEmptyString;

type NonEmptyString = string & {0: string}; // String with at least one character

Usage Examples:

import is from '@sindresorhus/is';

is.nonEmptyString('hello'); // => true
is.nonEmptyString('   '); // => true (has characters, even if whitespace)
is.nonEmptyString(''); // => false

is.nonEmptyStringAndNotWhitespace('hello'); // => true
is.nonEmptyStringAndNotWhitespace('hello world'); // => true
is.nonEmptyStringAndNotWhitespace('   '); // => false
is.nonEmptyStringAndNotWhitespace(''); // => false

// Filtering arrays
const values = ['property1', '', null, 'property2', '    ', undefined];
const validStrings = values.filter(is.nonEmptyStringAndNotWhitespace);
console.log(validStrings); // ['property1', 'property2']

// Type guard usage
function createSlug(title: unknown) {
  if (is.nonEmptyStringAndNotWhitespace(title)) {
    // title is now typed as NonEmptyString with guaranteed content
    return title.toLowerCase().replace(/\s+/g, '-');
  }
  throw new Error('Title must be a non-empty string with content');
}

Whitespace String Checking

Check if a string contains only whitespace characters.

/**
 * Check if value is a string containing only whitespace
 * @param value - Value to check
 * @returns True if value is whitespace-only string
 */
function isWhitespaceString(value: unknown): value is Whitespace;

Usage Examples:

import is from '@sindresorhus/is';

is.whitespaceString('   '); // => true
is.whitespaceString('\t\n\r '); // => true
is.whitespaceString(''); // => false (empty, not whitespace)
is.whitespaceString('hello'); // => false
is.whitespaceString(' hello '); // => false (contains non-whitespace)

// Type guard usage
function normalizeText(text: unknown) {
  if (is.string(text)) {
    if (is.whitespaceString(text)) {
      return ''; // Convert whitespace-only to empty
    }
    return text.trim();
  }
  return null;
}

Numeric String Validation

Check if a string represents a valid number.

/**
 * Check if string represents a valid number
 * @param value - Value to check
 * @returns True if value is numeric string
 */
function isNumericString(value: unknown): value is `${number}`;

Usage Examples:

import is from '@sindresorhus/is';

is.numericString('42'); // => true
is.numericString('3.14'); // => true
is.numericString('-123'); // => true
is.numericString('1e10'); // => true
is.numericString('Infinity'); // => true
is.numericString('-Infinity'); // => true

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

// Type guard usage
function parseUserInput(input: unknown) {
  if (is.string(input) && is.numericString(input)) {
    // input is typed as `${number}`
    return Number(input);
  }
  return null;
}

// Form validation
function validateNumberField(field: unknown) {
  if (is.nonEmptyStringAndNotWhitespace(field) && is.numericString(field)) {
    const num = Number(field);
    return { valid: true, value: num };
  }
  return { valid: false, error: 'Must be a valid number' };
}

URL String Validation

Check if a string is a valid URL.

/**
 * Check if string is a valid URL
 * @param value - Value to check
 * @returns True if value is valid URL string
 */
function isUrlString(value: unknown): value is string;

Usage Examples:

import is from '@sindresorhus/is';

is.urlString('https://example.com'); // => true
is.urlString('http://localhost:3000'); // => true
is.urlString('ftp://files.example.com'); // => true
is.urlString('mailto:user@example.com'); // => true

is.urlString('example.com'); // => false (no protocol)
is.urlString('https://'); // => false (incomplete)
is.urlString('not a url'); // => false

// Type guard usage
function openUrl(url: unknown) {
  if (is.urlString(url)) {
    // url is now typed as string and guaranteed to be valid URL
    window.open(url, '_blank');
  } else {
    throw new Error('Invalid URL provided');
  }
}

// URL validation with additional checks
function validateWebUrl(url: unknown) {
  if (is.urlString(url)) {
    const urlObj = new URL(url);
    if (urlObj.protocol === 'https:' || urlObj.protocol === 'http:') {
      return urlObj;
    }
    throw new Error('Only HTTP and HTTPS URLs are allowed');
  }
  throw new Error('Invalid URL format');
}

Usage Patterns

Form Field Validation

import is from '@sindresorhus/is';

interface FormData {
  name: string;
  email: string;
  age: number;
  website?: string;
}

function validateForm(data: Record<string, unknown>): FormData {
  const errors: string[] = [];
  
  // Name validation
  if (!is.nonEmptyStringAndNotWhitespace(data.name)) {
    errors.push('Name is required and cannot be empty');
  }
  
  // Email validation (basic)
  if (!is.nonEmptyStringAndNotWhitespace(data.email) || !data.email.includes('@')) {
    errors.push('Valid email is required');
  }
  
  // Age validation
  let age: number;
  if (is.numericString(data.age)) {
    age = Number(data.age);
  } else if (is.number(data.age)) {
    age = data.age;
  } else {
    errors.push('Age must be a number');
  }
  
  // Website validation (optional)
  let website: string | undefined;
  if (data.website !== undefined && data.website !== '') {
    if (is.urlString(data.website)) {
      website = data.website;
    } else {
      errors.push('Website must be a valid URL');
    }
  }
  
  if (errors.length > 0) {
    throw new Error(errors.join(', '));
  }
  
  return {
    name: data.name as string,
    email: data.email as string,
    age: age!,
    website
  };
}

Text Processing

import is from '@sindresorhus/is';

function cleanTextArray(texts: unknown[]): string[] {
  return texts
    .filter(is.string) // Only strings
    .filter(is.nonEmptyStringAndNotWhitespace) // With content
    .map(text => text.trim()) // Clean whitespace
    .filter((text, index, array) => array.indexOf(text) === index); // Remove duplicates
}

function processUserInput(input: unknown): string | null {
  if (!is.string(input)) {
    return null;
  }
  
  if (is.emptyStringOrWhitespace(input)) {
    return null;
  }
  
  // Clean and normalize
  return input.trim().replace(/\s+/g, ' ');
}

Configuration Validation

import is from '@sindresorhus/is';

interface Config {
  apiUrl: string;
  timeout: number;
  retries: number;
  debug: boolean;
}

function validateConfig(config: Record<string, unknown>): Config {
  // API URL validation
  if (!is.urlString(config.apiUrl)) {
    throw new Error('apiUrl must be a valid URL');
  }
  
  // Timeout validation
  let timeout: number;
  if (is.numericString(config.timeout)) {
    timeout = Number(config.timeout);
  } else if (is.number(config.timeout)) {
    timeout = config.timeout;
  } else {
    throw new Error('timeout must be a number');
  }
  
  // Retries validation  
  let retries: number;
  if (is.numericString(config.retries)) {
    retries = Number(config.retries);
  } else if (is.number(config.retries)) {
    retries = config.retries;
  } else {
    throw new Error('retries must be a number');
  }
  
  // Debug flag
  let debug: boolean;
  if (is.boolean(config.debug)) {
    debug = config.debug;
  } else if (is.string(config.debug)) {
    debug = config.debug.toLowerCase() === 'true';
  } else {
    debug = false;
  }
  
  return {
    apiUrl: config.apiUrl,
    timeout,
    retries,
    debug
  };
}

Search and Filter

import is from '@sindresorhus/is';

function searchItems(items: unknown[], query: unknown): string[] {
  if (!is.nonEmptyStringAndNotWhitespace(query)) {
    return [];
  }
  
  const searchTerm = query.toLowerCase();
  
  return items
    .filter(is.string)
    .filter(item => item.toLowerCase().includes(searchTerm));
}

function filterValidUrls(urls: unknown[]): string[] {
  return urls.filter(is.urlString);
}

Notes

  • Empty string checking distinguishes between '' and whitespace-only strings
  • isNonEmptyString() includes whitespace-only strings; use isNonEmptyStringAndNotWhitespace() to exclude them
  • Whitespace detection includes spaces, tabs, newlines, and other whitespace characters
  • Numeric string validation excludes 'NaN' but includes 'Infinity' and '-Infinity'
  • URL validation uses the URL constructor internally for accurate validation
  • URL validation supports all valid URL schemes (http, https, ftp, mailto, etc.)
  • All string checks work with TypeScript type guards for compile-time type narrowing
  • NonEmptyString type ensures string has at least one character at compile time

Install with Tessl CLI

npx tessl i tessl/npm-sindresorhus--is

docs

assertions.md

async.md

collections.md

index.md

numbers.md

objects.md

primitives.md

strings.md

typed-arrays.md

validation.md

web-apis.md

tile.json