Type check values with comprehensive TypeScript type guards and runtime assertions
—
Type checking for web-specific APIs including DOM elements, form data, URL objects, and browser-specific types.
Check if a value is an HTML DOM element.
/**
* Check if value is an HTML element
* @param value - Value to check
* @returns True if value is HTMLElement
*/
function isHtmlElement(value: unknown): value is HTMLElement;Usage Examples:
import is from '@sindresorhus/is';
// DOM elements
const div = document.createElement('div');
const button = document.querySelector('button');
const body = document.body;
is.htmlElement(div); // => true
is.htmlElement(button); // => true (if found)
is.htmlElement(body); // => true
// Non-elements
is.htmlElement(document); // => false
is.htmlElement(window); // => false
is.htmlElement('div'); // => false
// Type guard usage
function attachEventListener(element: unknown, event: string, handler: Function) {
if (is.htmlElement(element)) {
// element is now typed as HTMLElement
element.addEventListener(event, handler as EventListener);
return () => element.removeEventListener(event, handler as EventListener);
}
throw new Error('Element must be an HTMLElement');
}
// DOM manipulation
function setElementContent(element: unknown, content: string) {
if (is.htmlElement(element)) {
element.textContent = content;
element.style.display = 'block';
}
}Check if a value is a Blob object.
/**
* Check if value is a Blob
* @param value - Value to check
* @returns True if value is Blob
*/
function isBlob(value: unknown): value is Blob;Usage Examples:
import is from '@sindresorhus/is';
// Creating blobs
const textBlob = new Blob(['Hello, World!'], { type: 'text/plain' });
const jsonBlob = new Blob([JSON.stringify({data: 'test'})], { type: 'application/json' });
is.blob(textBlob); // => true
is.blob(jsonBlob); // => true
// File objects (inherit from Blob)
const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
const file = fileInput?.files?.[0];
if (file) {
is.blob(file); // => true (File extends Blob)
}
// Type guard usage
async function processBlob(data: unknown) {
if (is.blob(data)) {
// data is now typed as Blob
console.log('Blob size:', data.size);
console.log('Blob type:', data.type);
const text = await data.text();
console.log('Blob content:', text);
}
}
// File upload handling
function handleFileUpload(file: unknown) {
if (is.blob(file)) {
const formData = new FormData();
formData.append('file', file);
return formData;
}
throw new Error('Invalid file provided');
}Check if a value is a FormData object.
/**
* Check if value is FormData
* @param value - Value to check
* @returns True if value is FormData
*/
function isFormData(value: unknown): value is FormData;Usage Examples:
import is from '@sindresorhus/is';
const formData = new FormData();
formData.append('name', 'John');
formData.append('age', '30');
is.formData(formData); // => true
is.formData({}); // => false
is.formData(new URLSearchParams()); // => false
// Type guard usage
function submitForm(data: unknown) {
if (is.formData(data)) {
// data is now typed as FormData
for (const [key, value] of data.entries()) {
console.log(`${key}: ${value}`);
}
return fetch('/api/submit', {
method: 'POST',
body: data
});
}
throw new Error('Data must be FormData');
}
// Form processing
function processFormSubmission(form: HTMLFormElement, additionalData: Record<string, string>) {
const formData = new FormData(form);
// Add additional data
Object.entries(additionalData).forEach(([key, value]) => {
formData.append(key, value);
});
if (is.formData(formData)) {
return submitForm(formData);
}
}Check if a value is a URL object instance.
/**
* Check if value is a URL instance
* @param value - Value to check
* @returns True if value is URL instance
*/
function isUrlInstance(value: unknown): value is URL;Usage Examples:
import is from '@sindresorhus/is';
const url = new URL('https://example.com/path?query=value');
const invalidUrl = 'https://example.com';
is.urlInstance(url); // => true
is.urlInstance(invalidUrl); // => false (string, not URL instance)
// Type guard usage
function processUrl(url: unknown) {
if (is.urlInstance(url)) {
// url is now typed as URL
console.log('Protocol:', url.protocol);
console.log('Host:', url.host);
console.log('Pathname:', url.pathname);
console.log('Search params:', url.searchParams.toString());
return {
protocol: url.protocol,
host: url.host,
path: url.pathname,
query: Object.fromEntries(url.searchParams)
};
}
throw new Error('Invalid URL instance');
}
// URL manipulation
function addQueryParams(url: unknown, params: Record<string, string>) {
if (is.urlInstance(url)) {
Object.entries(params).forEach(([key, value]) => {
url.searchParams.set(key, value);
});
return url.toString();
}
throw new Error('URL must be a URL instance');
}Check if a value is a URLSearchParams object.
/**
* Check if value is URLSearchParams
* @param value - Value to check
* @returns True if value is URLSearchParams
*/
function isUrlSearchParams(value: unknown): value is URLSearchParams;Usage Examples:
import is from '@sindresorhus/is';
const params = new URLSearchParams('?name=John&age=30');
const paramsFromObject = new URLSearchParams({ city: 'NYC', country: 'US' });
is.urlSearchParams(params); // => true
is.urlSearchParams(paramsFromObject); // => true
is.urlSearchParams('?name=John&age=30'); // => false (string)
// Type guard usage
function processSearchParams(params: unknown) {
if (is.urlSearchParams(params)) {
// params is now typed as URLSearchParams
const result: Record<string, string> = {};
for (const [key, value] of params.entries()) {
result[key] = value;
}
return result;
}
throw new Error('Invalid URLSearchParams');
}
// Query string manipulation
function buildQueryString(params: unknown, additionalParams: Record<string, string>) {
let searchParams: URLSearchParams;
if (is.urlSearchParams(params)) {
searchParams = new URLSearchParams(params);
} else {
searchParams = new URLSearchParams();
}
Object.entries(additionalParams).forEach(([key, value]) => {
searchParams.set(key, value);
});
return searchParams.toString();
}import is from '@sindresorhus/is';
function setupEventDelegation(container: unknown, selector: string, handler: Function) {
if (!is.htmlElement(container)) {
throw new Error('Container must be an HTML element');
}
container.addEventListener('click', (event) => {
const target = event.target;
if (is.htmlElement(target) && target.matches(selector)) {
handler(event, target);
}
});
}
// Usage
setupEventDelegation(document.body, '.button', (event, button) => {
console.log('Button clicked:', button.textContent);
});import is from '@sindresorhus/is';
async function handleFileUpload(file: unknown): Promise<FormData> {
if (!is.blob(file)) {
throw new Error('File must be a Blob or File');
}
// Validate file size (10MB limit)
if (file.size > 10 * 1024 * 1024) {
throw new Error('File too large (max 10MB)');
}
// Validate file type
if (!file.type.startsWith('image/')) {
throw new Error('Only image files are allowed');
}
const formData = new FormData();
formData.append('file', file);
formData.append('timestamp', Date.now().toString());
return formData;
}
// Drag and drop handling
function setupDropZone(element: unknown) {
if (!is.htmlElement(element)) {
throw new Error('Drop zone must be an HTML element');
}
element.addEventListener('drop', async (event) => {
event.preventDefault();
const files = event.dataTransfer?.files;
if (files) {
for (const file of Array.from(files)) {
try {
const formData = await handleFileUpload(file);
console.log('File ready for upload:', formData);
} catch (error) {
console.error('File upload error:', error);
}
}
}
});
}import is from '@sindresorhus/is';
function parseUrl(input: unknown): {url: URL; params: Record<string, string>} {
let url: URL;
if (is.urlInstance(input)) {
url = input;
} else if (is.string(input)) {
try {
url = new URL(input);
} catch {
throw new Error('Invalid URL string');
}
} else {
throw new Error('Input must be URL instance or string');
}
const params: Record<string, string> = {};
for (const [key, value] of url.searchParams.entries()) {
params[key] = value;
}
return { url, params };
}
function buildApiUrl(baseUrl: string, endpoint: string, params?: unknown): string {
const url = new URL(endpoint, baseUrl);
if (params) {
let searchParams: URLSearchParams;
if (is.urlSearchParams(params)) {
searchParams = params;
} else if (is.plainObject(params)) {
searchParams = new URLSearchParams(params as Record<string, string>);
} else {
throw new Error('Params must be URLSearchParams or plain object');
}
url.search = searchParams.toString();
}
return url.toString();
}import is from '@sindresorhus/is';
function extractFormData(form: unknown): Record<string, string | File> {
if (!is.htmlElement(form) || form.tagName !== 'FORM') {
throw new Error('Input must be a form element');
}
const formData = new FormData(form as HTMLFormElement);
const result: Record<string, string | File> = {};
for (const [key, value] of formData.entries()) {
if (is.string(value)) {
result[key] = value;
} else if (is.blob(value)) {
result[key] = value as File;
}
}
return result;
}
function validateFormData(data: unknown): FormData {
if (!is.formData(data)) {
throw new Error('Input must be FormData');
}
// Validate required fields
const requiredFields = ['name', 'email'];
for (const field of requiredFields) {
if (!data.has(field)) {
throw new Error(`Missing required field: ${field}`);
}
}
return data;
}isUrlString() for strings)Install with Tessl CLI
npx tessl i tessl/npm-sindresorhus--is