How to fix 'exactOptionalPropertyTypes' requires strict mode in TypeScript

TypeScriptBEGINNERMEDIUMUpdated Dec 8, 2025ยท 147 views

This TypeScript configuration error occurs when you enable exactOptionalPropertyTypes without enabling strictNullChecks or the strict flag. The exactOptionalPropertyTypes compiler option depends on strict type checking to function properly.

Quick fix

Fixes 'exactOptionalPropertyTypes' requires strict mode

{
  "compilerOptions": {
    "strict": true,
    "exactOptionalPropertyTypes": true,
    "target": "ES2020",
    "module": "commonjs"
  }
}
  1. Enable the strict flag in tsconfig.json
  2. Enable only strictNullChecks if you want minimal changes
  3. Remove exactOptionalPropertyTypes if not ready for strict mode
  4. Check for conflicting inherited configurations
typescript โ€” error
{
"compilerOptions": {
"strict": true,
"exactOptionalPropertyTypes": true,
"target": "ES2020",
"module": "commonjs"
}
}
'exactOptionalPropertyTypes' requires strict mode

What this error means

The "'exactOptionalPropertyTypes' requires strict mode" error appears when you try to enable the exactOptionalPropertyTypes compiler option in tsconfig.json without having strictNullChecks enabled. This is a configuration dependency error, not a code error. The exactOptionalPropertyTypes flag was introduced in TypeScript 4.4 to make optional properties behave more strictly. It distinguishes between a property being omitted versus being explicitly set to undefined. However, this distinction only makes sense when strictNullChecks is enabled, as that's what makes undefined a distinct type. Unlike most strict-family options, exactOptionalPropertyTypes is NOT automatically included when you set "strict": true. You must enable it explicitly, but when you do, TypeScript requires that strictNullChecks (or the umbrella strict flag) is also enabled. Without strict null checking, the compiler cannot enforce the exact optional property semantics.

Typical symptoms

  • Compiler error: 'exactOptionalPropertyTypes' requires strict mode
  • TypeScript compilation fails when tsconfig.json has exactOptionalPropertyTypes: true
  • Error appears immediately after adding exactOptionalPropertyTypes to compiler options
  • Build process halts with configuration error before checking any code
  • IDE shows configuration error in tsconfig.json file

Common causes

  1. exactOptionalPropertyTypes is enabled but strict is set to false or omitted
  2. exactOptionalPropertyTypes is enabled but strictNullChecks is explicitly set to false
  3. Inheriting from a base tsconfig that disables strictNullChecks
  4. Migrating from JavaScript and enabling exactOptionalPropertyTypes before strict mode

How to fix "'exactOptionalPropertyTypes' requires strict mode"

1Enable the strict flag in tsconfig.json

The simplest fix is to enable the strict flag, which includes strictNullChecks and all other strict-family options:

json
{
  "compilerOptions": {
    "strict": true,
    "exactOptionalPropertyTypes": true,
    "target": "ES2020",
    "module": "commonjs"
  }
}

The strict flag enables:
- strictNullChecks (required for exactOptionalPropertyTypes)
- strictFunctionTypes
- strictBindCallApply
- strictPropertyInitialization
- noImplicitThis
- alwaysStrict
- noImplicitAny

After saving the file, run your TypeScript compiler:

bash
npx tsc
# or
npm run build

The configuration error should be resolved, though you may now see new type errors in your code from the stricter checking.

2Enable only strictNullChecks if you want minimal changes

If you don't want to enable all strict mode options yet, you can enable just strictNullChecks:

json
{
  "compilerOptions": {
    "strictNullChecks": true,
    "exactOptionalPropertyTypes": true,
    "target": "ES2020",
    "module": "commonjs"
  }
}

This satisfies the requirement for exactOptionalPropertyTypes while avoiding other strict checks.

However, note that strictNullChecks alone may still introduce many type errors in existing code:

typescript
// Without strictNullChecks, this is allowed:
let name: string = null;  // OK (bad!)

// With strictNullChecks, you'll get errors:
let name: string = null;  // Error: Type 'null' is not assignable to type 'string'

// Fix by allowing null explicitly:
let name: string | null = null;  // OK
3Remove exactOptionalPropertyTypes if not ready for strict mode

If enabling strict mode would introduce too many errors in your codebase, temporarily remove exactOptionalPropertyTypes:

json
{
  "compilerOptions": {
    // "exactOptionalPropertyTypes": true,  // Commented out
    "target": "ES2020",
    "module": "commonjs"
  }
}

This allows your project to compile without the configuration error. You can re-enable it later when you're ready to adopt stricter type checking.

Plan your migration:
1. First enable strict: true or strictNullChecks: true
2. Fix the resulting type errors incrementally
3. Then add exactOptionalPropertyTypes: true
4. Fix any new errors from exact optional semantics

4Check for conflicting inherited configurations

If you're using extends in your tsconfig.json, a parent config might be disabling strict mode:

json
// tsconfig.json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "exactOptionalPropertyTypes": true
  }
}

Check the base config:

bash
cat tsconfig.base.json

If the base config has strict or strictNullChecks set to false, override it:

json
// tsconfig.json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "strict": true,  // Override the base config
    "exactOptionalPropertyTypes": true
  }
}

Options in your config override inherited ones, so this will enable strict mode for your project.

5Verify configuration with tsc --showConfig

After making changes, verify the final effective configuration:

bash
npx tsc --showConfig

This shows the merged configuration after all extends and overrides:

json
{
  "compilerOptions": {
    "strict": true,
    "strictNullChecks": true,
    "exactOptionalPropertyTypes": true,
    // ... other options
  }
}

Look for both strictNullChecks and exactOptionalPropertyTypes showing as true.

If strictNullChecks shows as false, trace through your extends chain to find where it's being disabled.

Advanced notes

### What exactOptionalPropertyTypes Actually Does

With exactOptionalPropertyTypes enabled, optional properties are treated more precisely:

Without exactOptionalPropertyTypes:

typescript
interface User {
  email?: string;
}

// All of these are valid:
const user1: User = {};                    // email omitted
const user2: User = { email: "test@example.com" };  // email present
const user3: User = { email: undefined };  // email explicitly undefined

// The property exists with value undefined:
console.log("email" in user3);  // true

With exactOptionalPropertyTypes:

typescript
interface User {
  email?: string;
}

const user1: User = {};  // OK - email omitted
const user2: User = { email: "test@example.com" };  // OK
const user3: User = { email: undefined };
// Error: Type 'undefined' is not assignable to type 'string'
// with 'exactOptionalPropertyTypes: true'

// To allow explicit undefined, add it to the type:
interface User {
  email?: string | undefined;  // Now explicit undefined is allowed
}

### Why It Requires strictNullChecks

Without strictNullChecks, undefined is assignable to all types:

typescript
// With strictNullChecks: false
let name: string = undefined;  // Allowed (unsafe!)

In this mode, the distinction between email?: string and email?: string | undefined is meaningless because undefined is already part of string. The exactOptionalPropertyTypes feature cannot function without strict null checking.

### Migration Strategy for Large Codebases

If you have a large codebase and want to adopt exactOptionalPropertyTypes:

Step 1: Enable strict mode first

json
{
  "compilerOptions": {
    "strict": true
  }
}

Fix all the resulting errors. This may take time, but you can use @ts-expect-error or @ts-ignore temporarily:

typescript
// Temporary suppression during migration
// @ts-expect-error - TODO: Fix null handling
const value: string = potentiallyNull;

Step 2: Enable exactOptionalPropertyTypes

Once strict mode is stable, add:

json
{
  "compilerOptions": {
    "strict": true,
    "exactOptionalPropertyTypes": true
  }
}

Step 3: Fix new errors

Look for patterns like:

typescript
// Before
interface Config {
  timeout?: number;
}

function reset(config: Config) {
  config.timeout = undefined;  // Error with exactOptionalPropertyTypes
}

// Fix option 1: Delete the property
function reset(config: Config) {
  delete config.timeout;
}

// Fix option 2: Allow undefined explicitly
interface Config {
  timeout?: number | undefined;
}

### Recommended tsconfig.json for New Projects

For maximum type safety:

json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "node16",
    "moduleResolution": "node16",
    "lib": ["ES2022"],

    // Strict type checking
    "strict": true,
    "exactOptionalPropertyTypes": true,
    "noUncheckedIndexedAccess": true,
    "noPropertyAccessFromIndexSignature": true,

    // Additional strictness
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "allowUnusedLabels": false,

    // Emit
    "declaration": true,
    "sourceMap": true,
    "outDir": "./dist",

    // Other
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}

### Compatibility with Libraries

Some third-party libraries may have type definitions that are incompatible with exactOptionalPropertyTypes. If you encounter errors in node_modules/@types:

typescript
// Error in @types/some-library

You have several options:

1. Skip library checks (quickest):

json
{
  "compilerOptions": {
    "skipLibCheck": true  // Ignore errors in .d.ts files
  }
}

2. Report the issue to DefinitelyTyped or the library maintainer

3. Create a local type override in your project:

typescript
// types/library-fixes.d.ts
declare module "problematic-library" {
  export interface Config {
    option?: string | undefined;  // Add explicit undefined
  }
}

Frequently asked questions

What does "'exactOptionalPropertyTypes' requires strict mode" mean?
json without having strictNullChecks enabled. This is a configuration dependency error, not a code error. 4 to make optional properties behave more strictly.
How do I fix "'exactOptionalPropertyTypes' requires strict mode"?
This TypeScript configuration error occurs when you enable exactOptionalPropertyTypes without enabling strictNullChecks or the strict flag. The exactOptionalPropertyTypes compiler option depends on strict type checking to function properly.
What causes "'exactOptionalPropertyTypes' requires strict mode"?
exactOptionalPropertyTypes is enabled but strict is set to false or omitted exactOptionalPropertyTypes is enabled but strictNullChecks is explicitly set to false Inheriting from a base tsconfig that disables strictNullChecks
Is the "'exactOptionalPropertyTypes' requires strict mode" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading