TypeScript error

TS2375: undefined in an optional property, under exactOptionalPropertyTypes

  • Error TS2375
  • Reported with exactOptionalPropertyTypes
  • Tested with TypeScript 5.9

With exactOptionalPropertyTypes on, an optional property (nickname?: string) may be missing, but it may not be present with the value undefined. TS2375 reports an object that has it anyway, in a typed variable; TS2379 reports the same in an argument, and TS2412 in an assignment to the property.

The difference matters to code that checks "nickname" in profile or iterates over keys: a property set to undefined is there, a missing one is not. Without the option, TypeScript treats the two as the same.

At a glance

CodeTS2375
MessageType '{0}' is not assignable to type '{1}' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
Also on this page: TS2379 Argument of type '{0}' is not assignable to parameter of type '{1}' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
Also on this page: TS2412 Type '{0}' is not assignable to type '{1}' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the type of the target.
TypeScript's categoryerror
Listed underNull, undefined and unknown
Turned on by exactOptionalPropertyTypes
In .js files Reported when the file is checked: checkJs in jsconfig.json, or // @ts-check at the top of the file

The messages are TypeScript's own text from its diagnostic messages file (Apache-2.0); {0} and {1} are filled in by tsc for each error.

What it looks like

profile.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: profile.js(12,9): error TS2375: Type '{ name: string; nickname: string | undefined; }' is not assignable to type 'Profile' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. Types of property 'nickname' are incompatible. Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'. profile.js(14,8): error TS2379: Argument of type '{ name: string; nickname: string | undefined; }' is not assignable to parameter of type 'Profile' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. Types of property 'nickname' are incompatible. Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'. profile.js(16,3): error TS2412: Type 'undefined' is not assignable to type 'string' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the type of the target. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. profile.js(12,9): error TS2375: Type '{ name: string; nickname: string | undefined; }' is not assignable to type 'Profile' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. Types of property 'nickname' are incompatible. Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'. profile.js(14,8): error TS2379: Argument of type '{ name: string; nickname: string | undefined; }' is not assignable to parameter of type 'Profile' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. Types of property 'nickname' are incompatible. Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'. profile.js(16,3): error TS2412: Type 'undefined' is not assignable to type 'string' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the type of the target. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. profile.js(12,9): error TS2375: Type '{ name: string; nickname: string | undefined; }' is not assignable to type 'Profile' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. Types of property 'nickname' are incompatible. Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'. profile.js(14,8): error TS2379: Argument of type '{ name: string; nickname: string | undefined; }' is not assignable to parameter of type 'Profile' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. Types of property 'nickname' are incompatible. Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'. profile.js(16,3): error TS2412: Type 'undefined' is not assignable to type 'string' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the type of the target. checked 21 October 2026
/** @typedef {{ name: string, nickname?: string }} Profile */

/** @param {Profile} profile */
function save(profile) {
  return profile.name;
}

/** @param {string | undefined} nickname */
export function create(nickname) {
  /** @type {Profile} */
  const profile = { name: "Ada", nickname };error TS2375: Type '{ name: string; nickname: string | undefined; }' is not assignable to type 'Profile' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
  Types of property 'nickname' are incompatible.
    Type 'string | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.
  save({ name: "Ada", nickname });error TS2379: Argument of type '{ name: string; nickname: string | undefined; }' is not assignable to parameter of type 'Profile' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
  Types of property 'nickname' are incompatible.
    Type 'string | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.
  profile.nickname = undefined;error TS2412: Type 'undefined' is not assignable to type 'string' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the type of the target.
  return profile;
}
undefined in an optional property, under exactOptionalPropertyTypes.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": [],
    "exactOptionalPropertyTypes": true
  },
  "include": ["**/*.js"]
}

What causes it

  • An object literal copies a value that may be undefined into an optional property ({ name, nickname }).
  • Code clears an optional property by assigning undefined instead of deleting it.

How to fix it

Leave the property out when there is no value

Build the object without the property when the value is missing, and remove a property with delete rather than assigning undefined.

profile.js TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
/** @typedef {{ name: string, nickname?: string }} Profile */

/** @param {string | undefined} nickname */
export function create(nickname) {
  /** @type {Profile} */
  const profile = nickname === undefined ? { name: "Ada" } : { name: "Ada", nickname };
  delete profile.nickname;
  return profile;
}
Leave the property out when there is no value.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": [],
    "exactOptionalPropertyTypes": true
  },
  "include": ["**/*.js"]
}

Or allow undefined in the type

When undefined is a meaningful value for the property, say so: nickname?: string | undefined. Then both forms are accepted, as without the option.

profile.js TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
/** @typedef {{ name: string, nickname?: string | undefined }} Profile */

/** @param {string | undefined} nickname */
export function create(nickname) {
  /** @type {Profile} */
  const profile = { name: "Ada", nickname };
  profile.nickname = undefined;
  return profile;
}
Or say in the type that undefined is allowed.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": [],
    "exactOptionalPropertyTypes": true
  },
  "include": ["**/*.js"]
}

Gotchas

  • exactOptionalPropertyTypes needs strictNullChecks (part of strict), and it is not part of strict itself; the strict level of the jsconfig generator turns it on.
  • Library types that declare optional properties without | undefined reject an undefined value under this option, so passing a library an options object built from values that may be missing is a common source of TS2379.

Sources

Last reviewed 21 October 2026.