isMap
Determines whether a value is a Map object with enhanced type safety. Provides reliable Map detection using instanceof check with generic type support for type-safe Map validation and processing. Works with any Map instance regardless of key-value types.
Signature
const isMap: <T extends Map<any, any>>(value: unknown) => value is T
Parameters
| Name | Type | Description |
|---|---|---|
value | - | Value to test for Map type |
Returns
Type-safe boolean indicating whether the value is a Map
Examples
Basic Map detection
import { isMap } from '@winglet/common-utils';
// True cases - Map instances
console.log(isMap(new Map())); // true
console.log(isMap(new Map([['key', 'value']]))); // true
console.log(isMap(new Map([[1, 'one'], [2, 'two']]))); // true
const stringMap = new Map<string, number>();
stringMap.set('count', 42);
console.log(isMap(stringMap)); // true
// False cases - not Map instances
console.log(isMap({})); // false (plain object)
console.log(isMap({ size: 0, has: () => false })); // false (map-like object)
console.log(isMap(new Set())); // false (Set, not Map)
console.log(isMap(new WeakMap())); // false (WeakMap, not Map)
console.log(isMap([])); // false (array)
console.log(isMap('map')); // false (string)
console.log(isMap(null)); // false
console.log(isMap(undefined)); // false
Type-safe Map processing
function processMapData(data: unknown) {
if (isMap(data)) {
// TypeScript knows data is Map
console.log(`Map with ${data.size} entries`);
// Safe to use Map methods
const entries = Array.from(data.entries());
const keys = Array.from(data.keys());
const values = Array.from(data.values());
return {
size: data.size,
entries,
keys,
values,
isEmpty: data.size === 0
};
}
throw new Error('Expected Map instance');
}
// Usage
const userMap = new Map([
['john', { age: 30, role: 'admin' }],
['jane', { age: 25, role: 'user' }]
]);
const result = processMapData(userMap);
console.log('Processed map:', result);
Cache validation
interface CacheManager {
cache: unknown;
}
function validateCache(manager: CacheManager) {
if (!isMap(manager.cache)) {
throw new Error('Cache must be a Map instance');
}
return {
isValid: true,
size: manager.cache.size,
isEmpty: manager.cache.size === 0,
get(key: any) {
return manager.cache.get(key);
},
set(key: any, value: any) {
manager.cache.set(key, value);
},
clear() {
manager.cache.clear();
}
};
}
Data structure conversion
function convertToObject(mapOrObject: unknown): Record<string, any> {
if (isMap(mapOrObject)) {
const result: Record<string, any> = {};
for (const [key, value] of mapOrObject) {
// Convert key to string for object property
const stringKey = String(key);
result[stringKey] = value;
}
return result;
}
if (typeof mapOrObject === 'object' && mapOrObject !== null) {
return { ...mapOrObject };
}
throw new Error('Expected Map or object');
}
// Usage
const map = new Map([['name', 'John'], ['age', 30]]);
const obj = convertToObject(map); // { name: 'John', age: '30' }
Generic Map utilities
function mergeMap<K, V>(map1: unknown, map2: unknown): Map<K, V> {
if (!isMap<Map<K, V>>(map1) || !isMap<Map<K, V>>(map2)) {
throw new Error('Both arguments must be Map instances');
}
const result = new Map<K, V>(map1);
for (const [key, value] of map2) {
result.set(key, value);
}
return result;
}
function mapToArray<K, V>(mapInstance: unknown): Array<[K, V]> {
if (!isMap<Map<K, V>>(mapInstance)) {
throw new Error('Expected Map instance');
}
return Array.from(mapInstance.entries());
}
Configuration storage validation
interface AppSettings {
userPreferences: unknown;
sessionData: unknown;
}
function validateAppSettings(settings: AppSettings) {
const errors: string[] = [];
if (!isMap(settings.userPreferences)) {
errors.push('User preferences must be stored in a Map');
}
if (!isMap(settings.sessionData)) {
errors.push('Session data must be stored in a Map');
}
if (errors.length > 0) {
throw new Error(`Settings validation failed: ${errors.join(', ')}`);
}
return {
userPreferences: settings.userPreferences as Map<string, any>,
sessionData: settings.sessionData as Map<string, any>
};
}
Playground
import { isMap } from '@winglet/common-utils'; // True cases - Map instances console.log(isMap(new Map())); // true console.log(isMap(new Map([['key', 'value']]))); // true console.log(isMap(new Map([[1, 'one'], [2, 'two']]))); // true const stringMap = new Map<string, number>(); stringMap.set('count', 42); console.log(isMap(stringMap)); // true // False cases - not Map instances console.log(isMap({})); // false (plain object) console.log(isMap({ size: 0, has: () => false })); // false (map-like object) console.log(isMap(new Set())); // false (Set, not Map) console.log(isMap(new WeakMap())); // false (WeakMap, not Map) console.log(isMap([])); // false (array) console.log(isMap('map')); // false (string) console.log(isMap(null)); // false console.log(isMap(undefined)); // false
Notes
Key Features:
- Maintains insertion order (unlike plain objects in older JavaScript)
- Supports any type as keys (not just strings/symbols)
- Built-in iteration methods
- Direct size property
- Better performance for frequent additions/deletions
Use Cases:
- Cache implementation validation
- Data structure type checking
- API response validation
- Generic collection utilities
- Type guards for Map-specific operations
Related Types:
- Use
isWeakMap()for WeakMap detection - Use
isSet()for Set detection - Use
isObject()for general object detection - Use
typeof obj === 'object'for basic object checking
Performance: Direct instanceof check provides optimal performance.
Cross-frame Compatibility: Works correctly across different execution contexts.