How to Fix: Typescript definitions don’t exist for new `disableFontFamilyHashing` option in `next/font`

5 min read

The build fails because TypeScript is validating next/font options against type definitions that do not yet include disableFontFamilyHashing, even though the runtime may already recognize the option. That mismatch creates a classic runtime-versus-types version gap: your app code is valid for the installed behavior, but invalid for the installed typings.

Understanding the Root Cause

This issue happens when a newer Next.js font option is available in implementation or documentation, but the published TypeScript definitions for next/font have not caught up in the version you installed.

In practice, code like this triggers the error:

const geist = localFont({
  src: './GeistVF.woff2',
  disableFontFamilyHashing: true,
})

TypeScript checks the object literal against the declared type for the font loader options. If that type does not define disableFontFamilyHashing, the compiler throws an excess property error during build. This is why the problem appears even before runtime.

The root cause is usually one of these:

  • Your installed next package version includes incomplete or outdated typings.
  • Your lockfile resolved a version where the option exists only partially across packages.
  • Your editor or build cache is holding stale declaration files.
  • You are using strict TypeScript object checking, which correctly rejects unknown properties.

So the actual bug is not your font configuration. The bug is the missing property in the exported type declarations for next/font.

Step-by-Step Solution

The safest fix is to align your project with a Next.js version that includes both the feature and its matching type definitions. If that is not immediately possible, use a temporary local type patch.

1. Confirm the installed Next.js version

bun pm ls next

Or with npm:

npm ls next

If you are pinned to a version where the option is missing from typings, continue to the next step.

2. Upgrade Next.js to a version with corrected typings

Update next, then reinstall dependencies:

bun add next@latest
bun install

Or with npm:

npm install next@latest

Then rebuild:

bun run build

If the build passes, the issue was caused by outdated type declarations.

3. If upgrading is blocked, add a temporary local type workaround

When you cannot upgrade immediately, create a local declaration patch. Add a file such as types/next-font.d.ts:

declare module 'next/font/local' {
  export interface LocalFont<T extends string | undefined = undefined> {
    className: string
    style: { fontFamily: string; fontWeight?: number; fontStyle?: string }
    variable: T extends string ? T : never
  }

  export interface LocalFontOptions {
    src:
      | string
      | Array<{
          path: string
          weight?: string
          style?: string
        }>
    display?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional'
    weight?: string
    style?: string
    adjustFontFallback?: string | boolean
    fallback?: string[]
    preload?: boolean
    variable?: string
    declarations?: Array<{ prop: string; value: string }>
    disableFontFamilyHashing?: boolean
  }

  export default function localFont<T extends string | undefined = undefined>(
    options: LocalFontOptions
  ): LocalFont<T>
}

Make sure the file is included by TypeScript. In tsconfig.json, verify that your custom types folder is part of the project:

{
  "compilerOptions": {
    "strict": true
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "types/**/*.d.ts"
  ]
}

This local patch tells the compiler that disableFontFamilyHashing is a valid option until the upstream package fixes the declaration.

4. Prefer module augmentation only if the original types are augmentation-friendly

Some packages expose types in a way that supports declaration merging cleanly, while others do not. If a direct module augmentation works in your setup, you can use a smaller patch:

declare module 'next/font/local' {
  interface LocalFontOptions {
    disableFontFamilyHashing?: boolean
  }
}

If this does not take effect, use the fuller declaration shown above.

5. Clear caches after patching types

Cached build artifacts can keep serving old declarations. Remove caches and rebuild:

rm -rf .next
rm -rf node_modules
rm -f bun.lockb package-lock.json pnpm-lock.yaml yarn.lock
bun install
bun run build

Only delete the lockfile that matches your package manager.

6. Validate against the upstream issue and release notes

Check the relevant Next.js issue tracker and release notes to confirm whether the typings fix has landed. Once it has, remove your temporary patch to avoid conflicts with official declarations.

Common Edge Cases

  • Editor shows an error but build succeeds: your IDE may be using a different TypeScript server cache than the CLI. Restart the TypeScript server or reopen the workspace.
  • Build fails only on CI: local and CI environments may be installing different dependency versions because of lockfile drift or an unpinned next range.
  • Patch file is ignored: your .d.ts file is probably outside the tsconfig.json include paths.
  • Wrong module name: some projects import from next/font/local, others from a different entry point. Patch the exact module you import.
  • Monorepo conflicts: another package may provide a different Next.js version, causing type resolution to pick the wrong declarations.
  • Temporary cast hides future errors: avoid broad casts like as any unless absolutely necessary. They silence the current problem but also remove useful type safety.

If you need a short-term unblock and want minimal risk, a narrow local declaration patch is much safer than disabling type checking globally.

FAQ

Why does disableFontFamilyHashing work in examples but fail in my build?

Because examples may target a newer or internal implementation state, while your installed package exports older type definitions. TypeScript validates the declarations you actually have, not the behavior you expect.

Can I fix this with as any?

Yes, but it is a poor long-term solution. For example:

localFont({
  src: './GeistVF.woff2',
  disableFontFamilyHashing: true,
} as any)

This bypasses the error, but it also removes safety for the whole options object. A targeted declaration patch is cleaner.

Should I commit the local .d.ts workaround?

Yes, if your team or CI needs a stable build before the upstream fix is available. Commit it with a comment linking to the relevant upstream issue, then remove it after upgrading to a fixed release.

The most reliable resolution is to keep runtime code and TypeScript declarations on the same Next.js release line. When those drift apart, issues like this appear immediately in strict builds.

Leave a Reply

Your email address will not be published. Required fields are marked *