본문으로 건너뛰기

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​

NameTypeDescription
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 0 always 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