isUndefined
Determines whether a value is undefined with enhanced type safety.
Provides reliable undefined detection using strict equality check,
specifically identifying undefined values without including null.
More precise than isNil() when you need to distinguish between
null and undefined.
Signature
const isUndefined: (value?: unknown) => value is undefined
Parameters
| Name | Type | Description |
|---|---|---|
value | - | Value to test for undefined type |
Returns
Type-safe boolean indicating whether the value is undefined
Examples
Basic undefined detection
import { isUndefined } from '@winglet/common-utils';
// True cases - undefined value
console.log(isUndefined(undefined)); // true
console.log(isUndefined(void 0)); // true (void 0 produces undefined)
let uninitialized;
console.log(isUndefined(uninitialized)); // true
// False cases - not undefined
console.log(isUndefined(null)); // false (null, not undefined)
console.log(isUndefined(0)); // false (falsy but not undefined)
console.log(isUndefined('')); // false (falsy but not undefined)
console.log(isUndefined(false)); // false (falsy but not undefined)
console.log(isUndefined(NaN)); // false (falsy but not undefined)
console.log(isUndefined({})); // false (object)
console.log(isUndefined('undefined')); // false (string)
Optional parameter handling
function processValue(value?: string | null) {
if (isUndefined(value)) {
console.log('Parameter was not provided');
return 'DEFAULT_VALUE';
}
if (value === null) {
console.log('Parameter was explicitly set to null');
return 'NULL_VALUE';
}
// TypeScript knows value is string
console.log('Parameter provided:', value);
return value.toUpperCase();
}
// Usage demonstrates different scenarios
console.log(processValue()); // 'DEFAULT_VALUE' (undefined)
console.log(processValue(undefined)); // 'DEFAULT_VALUE' (undefined)
console.log(processValue(null)); // 'NULL_VALUE' (null)
console.log(processValue('hello')); // 'HELLO' (string)
Object property initialization
interface UserPreferences {
theme?: 'light' | 'dark';
language?: string;
notifications?: boolean;
}
function initializePreferences(prefs: UserPreferences = {}) {
const defaults = {
theme: 'light' as const,
language: 'en',
notifications: true
};
return {
theme: isUndefined(prefs.theme) ? defaults.theme : prefs.theme,
language: isUndefined(prefs.language) ? defaults.language : prefs.language,
notifications: isUndefined(prefs.notifications) ? defaults.notifications : prefs.notifications
};
}
// Usage
const prefs1 = initializePreferences({ theme: 'dark' });
console.log(prefs1); // { theme: 'dark', language: 'en', notifications: true }
const prefs2 = initializePreferences({});
console.log(prefs2); // { theme: 'light', language: 'en', notifications: true }
API response processing
interface ApiResponse {
status: string;
data?: any;
error?: string;
meta?: {
page?: number;
total?: number;
};
}
function processApiResponse(response: ApiResponse) {
const result = {
success: false,
data: null as any,
pagination: {
page: 1,
total: 0
},
error: null as string | null
};
result.success = response.status === 'success';
if (!isUndefined(response.data)) {
result.data = response.data;
}
if (!isUndefined(response.error)) {
result.error = response.error;
}
if (!isUndefined(response.meta)) {
if (!isUndefined(response.meta.page)) {
result.pagination.page = response.meta.page;
}
if (!isUndefined(response.meta.total)) {
result.pagination.total = response.meta.total;
}
}
return result;
}
Function argument validation
function createUser(
name: string,
email?: string,
age?: number,
options?: { sendWelcome?: boolean; role?: string }
) {
const user = {
name,
email: '',
age: 0,
sendWelcome: true,
role: 'user'
};
if (!isUndefined(email)) {
user.email = email;
}
if (!isUndefined(age)) {
user.age = age;
}
if (!isUndefined(options)) {
if (!isUndefined(options.sendWelcome)) {
user.sendWelcome = options.sendWelcome;
}
if (!isUndefined(options.role)) {
user.role = options.role;
}
}
return user;
}
// Usage
const user1 = createUser('John');
const user2 = createUser('Jane', 'jane@example.com', 25, { role: 'admin' });
Configuration merging
interface Config {
apiUrl?: string;
timeout?: number;
retries?: number;
debug?: boolean;
}
function mergeConfigs(base: Config, override: Config): Config {
const merged: Config = { ...base };
if (!isUndefined(override.apiUrl)) {
merged.apiUrl = override.apiUrl;
}
if (!isUndefined(override.timeout)) {
merged.timeout = override.timeout;
}
if (!isUndefined(override.retries)) {
merged.retries = override.retries;
}
if (!isUndefined(override.debug)) {
merged.debug = override.debug;
}
return merged;
}
// Usage
const baseConfig = { apiUrl: 'https://api.example.com', timeout: 5000, debug: false };
const userConfig = { timeout: 10000, debug: true };
const final = mergeConfigs(baseConfig, userConfig);
// { apiUrl: 'https://api.example.com', timeout: 10000, debug: true }
Type-safe property access
function safeGet<T, K extends keyof T>(obj: T, key: K): T[K] | 'MISSING' {
const value = obj[key];
if (isUndefined(value)) {
return 'MISSING' as T[K] | 'MISSING';
}
return value;
}
function hasProperty<T, K extends keyof T>(obj: T, key: K): boolean {
return !isUndefined(obj[key]);
}
// Usage
const data = { name: 'John', age: undefined as number | undefined };
console.log(safeGet(data, 'name')); // 'John'
console.log(safeGet(data, 'age')); // 'MISSING'
console.log(hasProperty(data, 'name')); // true
console.log(hasProperty(data, 'age')); // false
Environment variable processing
function getEnvConfig() {
const env = process.env;
return {
nodeEnv: isUndefined(env.NODE_ENV) ? 'development' : env.NODE_ENV,
port: isUndefined(env.PORT) ? 3000 : parseInt(env.PORT, 10),
dbUrl: isUndefined(env.DATABASE_URL) ? 'sqlite://memory' : env.DATABASE_URL,
debug: isUndefined(env.DEBUG) ? false : env.DEBUG === 'true'
};
}
// Handles both missing environment variables and empty strings
function getRequiredEnv(name: string): string {
const value = process.env[name];
if (isUndefined(value)) {
throw new Error(`Required environment variable ${name} is not defined`);
}
if (value === '') {
throw new Error(`Required environment variable ${name} is empty`);
}
return value;
}
Playground
import { isUndefined } from '@winglet/common-utils'; // True cases - undefined value console.log(isUndefined(undefined)); // true console.log(isUndefined(void 0)); // true (void 0 produces undefined) let uninitialized; console.log(isUndefined(uninitialized)); // true // False cases - not undefined console.log(isUndefined(null)); // false (null, not undefined) console.log(isUndefined(0)); // false (falsy but not undefined) console.log(isUndefined('')); // false (falsy but not undefined) console.log(isUndefined(false)); // false (falsy but not undefined) console.log(isUndefined(NaN)); // false (falsy but not undefined) console.log(isUndefined({})); // false (object) console.log(isUndefined('undefined')); // false (string)
Notes
Key Differences from Similar Functions:
- More specific than
isNil()(which includes null) - Uses strict equality (
===) for precise undefined detection - Important for APIs where null and undefined have different meanings
- Critical for optional parameter handling
JavaScript Undefined Behavior:
- Uninitialized variables are undefined
- Missing object properties return undefined
- Missing function parameters are undefined
void 0always produces undefined- Array holes contain undefined
Use Cases:
- Optional parameter validation
- Object property initialization
- Configuration merging
- API response processing
- Environment variable handling
- Type-safe property access
Performance: Direct strict equality comparison provides optimal performance.
Related Functions:
- Use
isNil()when null and undefined should be treated the same - Use
isNull()for null-only checking - Use
isNotNil()to exclude both null and undefined - Use
typeof value === 'undefined'for alternative checking