Type check values with comprehensive TypeScript type guards and runtime assertions
—
String-specific validation including empty strings, whitespace detection, numeric strings, URL strings, and text content validation.
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 stringsUsage 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');
}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 characterUsage 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');
}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;
}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' };
}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');
}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
};
}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, ' ');
}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
};
}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);
}'' and whitespace-only stringsisNonEmptyString() includes whitespace-only strings; use isNonEmptyStringAndNotWhitespace() to exclude them'NaN' but includes 'Infinity' and '-Infinity'URL constructor internally for accurate validationNonEmptyString type ensures string has at least one character at compile timeInstall with Tessl CLI
npx tessl i tessl/npm-sindresorhus--is