How to fix Type definition file must have .d.ts extension in TypeScript

TypeScriptINTERMEDIATEMEDIUMUpdated Dec 11, 2025ยท 94 views

TypeScript only accepts .d.ts files as declaration sources, so pointing a typeRoots, types, or package types path at a .ts file triggers this error. Rename the declaration material to .d.ts and regenerate your package.ts output before publishing so the compiler can safely load the definitions.

Quick fix

Fixes Type definition file must have .d.ts extension

mv src/types/ambient-declarations.ts src/types/ambient-declarations.d.ts
  1. Rename the offending declaration file to .d.ts
  2. Restrict typeRoots / types to directories that actually contain .d.ts files
  3. Emit real .d.ts output instead of referencing your .ts sources
typescript โ€” error
mv src/types/ambient-declarations.ts src/types/ambient-declarations.d.ts
Type definition file must have .d.ts extension

What this error means

The compiler emits "Type definition file must have .d.ts extension" whenever it resolves a declaration file that does not end with .d.ts. Declaration lookups originate from tsconfig's `types` / `typeRoots` settings or from package.json's `types` / `typings` entry, so the compiler refuses to treat an implementation (.ts) file as a declaration source. TypeScript deliberately keeps declarations and runtime code separate. .d.ts files describe the exported API surface without containing JavaScript, which allows the compiler to load ambient types without executing code. When a file is missing the .d.ts suffix, the compiler cannot know whether it should parse it as generated declaration output or as another implementation module, so it raises this error instead of silently misinterpreting your types.

Typical symptoms

  • tsc (or tsc --build) fails with "Type definition file must have .d.ts extension", usually before any other diagnostics appear
  • tsserver/VS Code highlights the offending path as a declaration problem
  • The error pops up after adding a custom type declaration directory to typeRoots
  • Publishing a library fails because package.json types now point at an index.ts file
  • The error can appear during npm pack when the distributed types directory still contains .ts files
  • A clean npm install followed by tsc still fails even though only declaration files are bundled
  • CI linting catches the failure when declaration files are emitted to dist/types but renamed incorrectly

Common causes

  1. typeRoots or types in tsconfig.json points to a directory/file that contains .ts or .tsx sources instead of .d.ts
  2. package.json types/typings references an entry point that still uses the .ts extension instead of the emitted .d.ts
  3. You manually authored ambient declarations but forgot to rename the file to .d.ts before publishing
  4. A build step copies .ts files into dist/types expecting the consumer to compile them, which breaks the compiler check
  5. You configured a monorepo so that declaration files still live next to implementation files with .ts extension
  6. tsc --emitDeclarationOnly generates declarations into a folder that also contains .ts files with the same name
  7. A third-party package ships a .ts declaration stub in node_modules/@types, so TypeScript rejects it
  8. Custom script or bundler concatenated declarations without enforcing the .d.ts suffix

How to fix "Type definition file must have .d.ts extension"

1Rename the offending declaration file to .d.ts

If you wrote the declaration manually, rename it to have the exact .d.ts suffix and update any references to it:

bash
mv src/types/ambient-declarations.ts src/types/ambient-declarations.d.ts

Then adjust package.json so the types field points to a .d.ts file:

json
{
  "types": "dist/types/index.d.ts"
}

TypeScript only loads files that end with .d.ts, so the rename is the easiest fix when the file was already just a declaration file with ambient namespaces or module augmentations.

2Restrict typeRoots / types to directories that actually contain .d.ts files

Open your tsconfig.json and make sure the compilerOptions look like this:

json
{
  "compilerOptions": {
    "typeRoots": ["./node_modules/@types", "./src/types"],
    "types": ["node", "my-types"]
  }
}

If you previously pointed to a directory with implementation (.ts) files, remove that path. Directories listed under typeRoots are scanned for .d.ts files only, so shrinking the list to actual declaration bundles prevents the compiler from seeing .ts files and complaining.

3Emit real .d.ts output instead of referencing your .ts sources

Let TypeScript generate declarations from your implementation files so consumers get clean .d.ts files:

json
{
  "compilerOptions": {
    "declaration": true,
    "emitDeclarationOnly": true,
    "declarationDir": "dist/types",
    "outDir": "dist",
    "declarationMap": true
  }
}

After running tsc, publish the generated dist/types folder. The entry in package.json should point at dist/types/index.d.ts and any manual scripts that previously copied .ts files into that folder can be removed.

Advanced notes

TypeScript refuses to load a declaration file without .d.ts so that the compiler can keep the code/ambient split explicit. If you need to expose a type-only API, either ship the generated .d.ts files or move the declarations into a proper ambient module after compiling. Bundlers sometimes emit index.d.ts alongside .js, so double-check that the bundler does not accidentally copy .ts leftovers into the declaration directory.

Frequently asked questions

What does "Type definition file must have .d.ts extension" mean?
ts. ts) file as a declaration source. TypeScript deliberately keeps declarations and runtime code separate.
How do I fix "Type definition file must have .d.ts extension"?
TypeScript only accepts .d.ts files as declaration sources, so pointing a typeRoots, types, or package types path at a .ts file triggers this error. Rename the declaration material to .d.ts and regenerate your package.ts output before publishing so the compiler can safely load the definitions.
What causes "Type definition file must have .d.ts extension"?
typeRoots or types in tsconfig.json points to a directory/file that contains .ts or .tsx sources instead of .d.ts package.json types/typings references an entry point that still uses the .ts extension instead of the emitted .d.ts You manually authored ambient declarations but forgot to rename the file to .d.ts before publishing
Is the "Type definition file must have .d.ts extension" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading