Byte Corner

#typescript

•

3 min read

•

October 5, 2026

An Optional Property Isn't the Same as undefined

An optional property and an explicit undefined value can look identical in JavaScript, but TypeScript treats them differently.

Matej Bošnjak
Matej Bošnjak

October 5, 2026

#typescript
#type-systems
#undefined
An Optional Property Isn't the Same as undefined

undefined Is Not the Same as Not Being There

An optional property looks a lot like a property whose value can be undefined.

But they are not quite the same thing.

That difference becomes important when you care about whether a property exists at all.

🔴 The Problem

Consider these two objects:

const a = {};

const b = {
  value: undefined,
};

At a glance, they can look equivalent.

Reading value gives you undefined in both cases:

console.log(a.value);
console.log(b.value);

Both print:

undefined

But the objects are different.

One does not have a value property.

The other does.

You can see that with:

console.log("value" in a);
console.log("value" in b);

The result is:

false
true

That distinction is easy to miss because normal property access hides it.

🟢 The TypeScript Part

Now look at this type:

type Config = {
  value?: string;
};

The ? means the property may be absent.

So this is valid:

const config: Config = {};

And this is also valid:

const config: Config = {
  value: "hello",
};

Depending on your TypeScript configuration, this can also be valid:

const config: Config = {
  value: undefined,
};

But those last two objects still represent different runtime states.

The first has a value.

The second has a property whose value is undefined.

That difference matters when the presence of the property itself has meaning.

⚡ The Part That Usually Bites

Imagine an API where omitting a property means:

"Don't change this setting."

while explicitly passing undefined has a different meaning.

Or imagine code that checks whether a property was supplied:

if ("value" in config) {
  // the caller supplied the property
}

Now these two values are no longer interchangeable:

const a: Config = {};

const b: Config = {
  value: undefined,
};

The type might make them look similar.

The runtime object does not.

This becomes especially interesting when objects are passed between functions, merged together, serialized, or used as configuration.

🧠 The TypeScript Detail

There is a compiler option specifically related to this distinction:

{
  "compilerOptions": {
    "exactOptionalPropertyTypes": true
  }
}

With this enabled, an optional property means the property can be omitted.

It does not automatically mean you can explicitly assign undefined.

So:

type Config = {
  value?: string;
};

allows:

const a: Config = {};

and:

const b: Config = {
  value: "hello",
};

But this becomes an error:

const c: Config = {
  value: undefined,
};

If you actually want to allow the property to exist with undefined, say so:

type Config = {
  value?: string | undefined;
};

Now the type describes both possibilities:

property is absent
        OR
property exists with undefined
        OR
property exists with a string

That is a much more precise description of the object.

🧩 When Could This Be Useful?

This distinction is especially useful for configuration and update objects.

Consider:

type UserUpdate = {
  name?: string;
  email?: string;
};

An update function might interpret an omitted property as:

"Leave the existing value alone."

while a present property could mean:

"Change this field."

That makes property presence part of the API's meaning.

The same idea appears when dealing with object merging:

const defaults = {
  color: "orange",
};

const options = {
  color: undefined,
};

const result = {
  ...defaults,
  ...options,
};

The property was not missing.

It was explicitly present.

So the resulting object contains:

{
  color: undefined;
}

That can be very different from simply not providing color at all.

🧠 The Takeaway

An optional property is about presence.

undefined is about value.

Those two concepts often produce the same result when you simply read the property:

object.value;

But they can represent different states.

Once your application cares about whether something was omitted or explicitly provided, that difference stops being a TypeScript technicality.

It becomes part of the API design.

value?: string

does not simply mean:

"value can be undefined"

It starts with:

"this property may not exist"

And sometimes, that is exactly the distinction your code needs.

Back to all articles

Byte Corner

Byte Corner is still growing.

Not everything needs to be practical to be worth understanding. Sometimes you just find an interesting question and follow the rabbit hole.

const curious = true;

while (curious) {

keepDigging();

}

Follow Byte Corner

Get notified when we publish new articles. No spam, just great dev content.

Follow on LinkedInFollow on daily.dev

bytecorner

© 2026 bytecorner.dev

Small reads. Big understanding.