Skip to content

Backend SDK declarations fail with exactOptionalPropertyTypes and skipLibCheck=false #9963

Description

@shreyasx19

Backend SDK declarations fail with exactOptionalPropertyTypes and skipLibCheck=false

Summary

Importing @clerk/backend 3.20.1 with @clerk/shared 4.36.0 produces eight TypeScript declaration errors with strict checking, exactOptionalPropertyTypes=true and skipLibCheck=false. The reproduction below uses no framework, provider account or credentials.

Environment: Windows x64, Node 24.15.0, npm 11.12.1, TypeScript 6.0.3. The SDK pair matches the latest stable npm tags checked on 2026-09-28.

Reproduction

Create these three files in an empty directory, then run npm install --ignore-scripts --no-audit and npm run check. A generated exact lockfile was used for the observed run.

package.json

{
  "name": "clerk-strict-declaration-repro",
  "version": "0.0.0",
  "private": true,
  "type": "module",
  "engines": { "node": "24.15.0", "npm": "11.12.1" },
  "scripts": { "check": "tsc --noEmit --pretty false" },
  "dependencies": {
    "@clerk/backend": "3.20.1",
    "@clerk/shared": "4.36.0",
    "react": "19.3.0",
    "react-dom": "19.3.0"
  },
  "devDependencies": {
    "@types/node": "24.19.0",
    "@types/react": "19.3.0",
    "@types/react-dom": "19.3.0",
    "typescript": "6.0.3"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["dom", "dom.iterable", "esnext"],
    "module": "esnext",
    "moduleResolution": "bundler",
    "strict": true,
    "exactOptionalPropertyTypes": true,
    "noUncheckedIndexedAccess": true,
    "skipLibCheck": false,
    "noEmit": true,
    "esModuleInterop": true,
    "jsx": "react-jsx"
  },
  "include": ["index.ts"]
}

index.ts

import { createClerkClient } from '@clerk/backend';

export type Client = ReturnType<typeof createClerkClient>;

// Compile only. No client is created and no credentials or network calls run.
export async function authenticate(client: Client, request: Request, origin: string) {
  const state = await client.authenticateRequest(request, {
    acceptsToken: 'session_token', authorizedParties: [origin],
  });
  const auth = state.toAuth();
  if (!auth?.userId || !auth.sessionId || !auth.sessionClaims) return null;
  const session = await client.sessions.getSession(auth.sessionId);
  return {
    issuer: auth.sessionClaims.iss, subject: auth.userId,
    sessionId: session.id, status: session.status,
    tokenExpiresAt: auth.sessionClaims.exp * 1000, expiresAt: session.expireAt,
  };
}

Expected and observed

Expected: the public authentication/session types compile with full declaration checking. Observed: tsc exits 2 with two exact-optional class/interface errors, five missing optional modules and a missing appearance-registry theme.

> clerk-strict-declaration-repro@0.0.0 check
> tsc --noEmit --pretty false

node_modules/@clerk/shared/dist/errors/clerkApiError.d.mts(7,15): error TS2420: Class 'ClerkAPIError<Meta>' incorrectly implements interface 'ClerkAPIError'.
  Types of property 'longMessage' are incompatible.
    Type 'string | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.
node_modules/@clerk/shared/dist/errors/clerkApiResponseError.d.mts(16,3): error TS2416: Property 'errors' in type 'ClerkAPIResponseError' is not assignable to the same property in base type 'ClerkAPIResponseError'.
  Type 'ClerkAPIError<any>[]' is not assignable to type 'ClerkAPIError[]'.
    Type 'ClerkAPIError<any>' is not assignable to type 'ClerkAPIError' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
      Types of property 'longMessage' are incompatible.
        Type 'string | undefined' is not assignable to type 'string'.
          Type 'undefined' is not assignable to type 'string'.
node_modules/@clerk/shared/dist/moduleManager.d.mts(3,36): error TS2307: Cannot find module '@zxcvbn-ts/core' or its corresponding type declarations.
node_modules/@clerk/shared/dist/moduleManager.d.mts(4,47): error TS2307: Cannot find module '@zxcvbn-ts/language-common' or its corresponding type declarations.
node_modules/@clerk/shared/dist/moduleManager.d.mts(5,38): error TS2307: Cannot find module '@base-org/account' or its corresponding type declarations.
node_modules/@clerk/shared/dist/moduleManager.d.mts(6,41): error TS2307: Cannot find module '@coinbase/wallet-sdk' or its corresponding type declarations.
node_modules/@clerk/shared/dist/moduleManager.d.mts(7,38): error TS2307: Cannot find module '@stripe/stripe-js' or its corresponding type declarations.
node_modules/@clerk/shared/dist/types/clerk.d.mts(48,53): error TS2339: Property 'theme' does not exist on type 'ClerkAppearanceRegistry'.

The class declares longMessage as string | undefined while its interface declares longMessage?: string. Those declarations conflict under exactOptionalPropertyTypes. Installing optional UI packages would not resolve that class/interface conflict.

Other tested versions

The same compiler flags and authentication/session consumer fail with these exact pairs. No dependency overrides or declaration patches were used.

Backend Shared Result
3.20.1 4.36.0 8 diagnostics
2.33.7 3.48.0, types 4.101.27 32 diagnostics
3.20.2-canary.v20260926175024 4.37.0-canary.v20260926175024 8 diagnostics
2.33.3 3.47.5, types 4.101.23 32 diagnostics
3.2.14 4.8.3 42 diagnostics

The canary was tested only to check for an upcoming fix. The two older pairs are the first versions patched for GHSA-w24r-5266-9c3c. I found the older closed strict-types issue #326, but it concerns the former backend-core package and does not resolve this reproduction.

Is there a supported exact dependency pair or public entry point that retains authenticateRequest, sessionClaims and sessions.getSession types while passing these compiler settings? If not, can the published declarations be corrected without requiring skipLibCheck or application-side declaration shims?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

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