Skip to content

workbox-precaching: TypeScript type checking fails with exactOptionalPropertyTypes: true #3490

Description

@djcsdy

With TypeScript 5.9.3, type checking fails in projects that use workbox-precaching when exactOptionalPropertyTypes is enabled:

./node_modules/workbox-precaching/PrecacheFallbackPlugin.d.ts:18:15 - error TS2420: Class 'PrecacheFallbackPlugin' incorrectly implements interface 'WorkboxPlugin'.
  Types of property 'handlerDidError' are incompatible.
    Type 'HandlerDidErrorCallback | undefined' is not assignable to type 'HandlerDidErrorCallback'.
      Type 'undefined' is not assignable to type 'HandlerDidErrorCallback'.

The problem is in workbox-precaching/PrecacheFallbackPlugin.d.ts:

declare class PrecacheFallbackPlugin implements WorkboxPlugin {
    // ...
    handlerDidError: WorkboxPlugin['handlerDidError'];
}

In workbox-core/types.d.ts, handlerDidError is optional:

export declare interface WorkboxPlugin {
    // ...
    handlerDidError?: HandlerDidErrorCallback;
    // ...
}

Because handlerDidError is optional, WorkboxPlugin['handlerDidError'] resolves to HandlerDidErrorCallback | undefined.

With exactOptionalPropertyTypes enabled, TypeScript distinguishes between the case where a property is not present and the case where it is present and explicitly set to undefined (JavaScript also has subtly different behaviour in these two cases, so this TypeScript setting sometimes catches actual bugs).

The interface declaration of WorkboxPlugin specifies that handlerDidError is optional, but that if it is present then it must have the type HandlerDidErrorCallback.

HandlerDidErrorCallback | undefined is not assignable to HandlerDidErrorCallback, therefore PrecacheFallbackPlugin does not implement the WorkboxPlugin interface correctly.

PrecacheFallbackPlugin should instead be declared like:

declare class PrecacheFallbackPlugin implements WorkboxPlugin {
    // ...
    handlerDidError: HandlerDidErrorCallback;
}

or possibly

declare class PrecacheFallbackPlugin implements WorkboxPlugin {
    // ...
    handlerDidError?: HandlerDidErrorCallback;
}

Or, alternatively, if workbox allows explicitly setting optional properties to undefined, then undefined should be added to the types of optional properties, for example:

export declare interface WorkboxPlugin {
    // ...
    handlerDidError?: HandlerDidErrorCallback | undefined;
    // ...
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions