Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

No. In TypeScript, an optional property may be left out of an object; a property explicitly set to undefined is still present. Reading either one can produce undefined, but checks and object operations can tell the difference.

What does the question mark mean?

In a property declaration such as colorThemeOverride?: "dark" | "light", ? means an object is allowed to omit that key. It does not guarantee that reading the property returns a usable string: if the key is absent, the read evaluates to undefined.

interface Settings {
  colorThemeOverride?: "dark" | "light";
}

const omitted: Settings = {};
const presentUndefined = { colorThemeOverride: undefined };

omitted.colorThemeOverride; // undefined
presentUndefined.colorThemeOverride; // undefined

The two reads have the same result, but the objects are not equivalent. The first has no colorThemeOverride key; the second has that key with an undefined value.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How can you tell whether the key exists?

At runtime, the in operator checks whether a property exists on an object or its prototype chain. For own-property checks, use Object.hasOwn where supported, or Object.prototype.hasOwnProperty.call.

"colorThemeOverride" in omitted; // false
"colorThemeOverride" in presentUndefined; // true

Object.prototype.hasOwnProperty.call(omitted, "colorThemeOverride"); // false
Object.prototype.hasOwnProperty.call(presentUndefined, "colorThemeOverride"); // true

Presence can also affect enumeration and copying. For example, Object.keys includes an own enumerable key whose value is undefined, and object spread copies that key; neither operation can copy a key that is absent.

Object.keys(omitted); // []
Object.keys(presentUndefined); // ["colorThemeOverride"]

const copy = { ...presentUndefined }; // retains colorThemeOverride

That distinction matters when code treats omission as “leave the existing value unchanged” but treats an explicitly supplied value—including undefined—as an update. It can also matter when serializing or merging objects, since those operations may handle absent keys and present keys differently.

Rank #2
TypeScript Programming Language - Software Engineer & Coder T-Shirt
  • TypeScript implements a superset of syntax for strictly typed development, facilitating deep static analysis and enhanced development environment integration. The compiler translates source into standard script formats, ensuring parity across any runtime.
  • TypeScript is ideal for front-end developers, full-stack engineers, and software architects who build large-scale web applications. It serves those looking to improve code excellence, reduce bugs through static checking, and maintain complex projects more.
  • Lightweight, Classic fit, Double-needle sleeve and bottom hem

When does TypeScript allow an explicit undefined value?

It depends on the compiler option exactOptionalPropertyTypes. With the default false behavior, TypeScript accepts an explicit undefined assignment to an optional property, even if the declared value type does not include it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

With exactOptionalPropertyTypes: true, colorThemeOverride?: "dark" | "light" permits omitting the key but rejects writing colorThemeOverride: undefined. The official TSConfig documentation explains that an explicitly undefined property is not the same as an undefined property that is not defined.

interface Settings {
  colorThemeOverride?: "dark" | "light";
}

const omitted: Settings = {}; // allowed
const explicit: Settings = { colorThemeOverride: undefined };
// Allowed when exactOptionalPropertyTypes is false;
// rejected when it is true.

If the API intentionally accepts both omission and explicit undefined, include it in the property’s type:

interface Settings {
  colorThemeOverride?: "dark" | "light" | undefined;
}

const explicit: Settings = { colorThemeOverride: undefined }; // allowed

The option was introduced in TypeScript 4.4. It is not included automatically by strict and requires strictNullChecks. The TypeScript 4.4 release notes describe the exact interpretation of optional property types. Check the project’s tsconfig.json before interpreting an assignment error or assuming that a library’s optional properties reject explicit undefined.

Which declaration should you use?

Choose the declaration based on whether the key itself must exist and whether an explicit undefined is a meaningful input.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Declaration May omit the key? Can explicitly assign undefined? Typical meaning
p?: T Yes Depends on exactOptionalPropertyTypes; accepted when it is off, rejected when it is on unless undefined is in T. The caller may leave the property out.
p?: T | undefined Yes Yes Omission and explicit undefined are both accepted.
p: T | undefined No Yes The key must be present, but its value may be undefined.

Use p?: T when omission is the intended optional state. Add | undefined when callers should be permitted to pass that value explicitly. Use p: T | undefined when every object must contain the key, even if the current value is undefined.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

What should you do when reading an optional property?

Optionality is not a read-side guarantee. Even with exact optional-property checking enabled, the key may be absent, so handle the possible undefined result before using a value as T.

const theme = settings.colorThemeOverride;

if (theme !== undefined) {
  // theme is "dark" | "light" here
}

If your logic needs to distinguish “key absent” from “key present with undefined,” check property presence rather than only comparing the read value with undefined. Accessing a missing property evaluates to undefined; it does not make the property exist.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.