Skip to content

TypeScript complains about overwriting .d.ts files that are potentially known outputs #16749

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ORESoftware opened this issue Jun 26, 2017 · 30 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@ORESoftware
Copy link

ORESoftware commented Jun 26, 2017

Using tsc at the command line, I got

error TS5055: Cannot write file '/Users/alexamil/WebstormProjects/oresoftware/ldap-pool/index.d.ts' because it would overwrite input file.

why? :)

my tsconfig.json file is as follows

{
  "compilerOptions": {
    "declaration": true,
    "baseUrl": ".",
    "types": [
      "node"
    ],
    "typeRoots": [
      "node_modules/@types"
    ],
    "target": "es5",
    "module": "commonjs",
    "noImplicitAny": true,
    "removeComments": true,
    "allowUnreachableCode": true,
    "lib": [
      "es2015",
      "es2016",
      "es2017"
    ]
  },
  "compileOnSave": false,
  "exclude": [
    "node_modules"
  ]
}
@ORESoftware
Copy link
Author

nope, it's not because of the include property, I removed it, and same problem. this is a weird one folks.

@DanielRosenwasser
Copy link
Member

If you remove the include field, then it implicitly includes everything. I guess you could consider excluding .d.ts files, but the point is that .d.ts is a valid input as well.

It would be helpful to get feedback from others on this.

@DanielRosenwasser DanielRosenwasser added Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript labels Jun 27, 2017
@the1mills
Copy link

But generated .d.ts files are not input files!

As you can see in this case that it's being autogenerated.

Why would tsc complain?

@DanielRosenwasser
Copy link
Member

.d.ts files could be generated, or could be written by hand to fill in for an input .js file. Keeping this in mind is important, especially as we consider supporting .d.ts emit from .js files going forward.

@DanielRosenwasser DanielRosenwasser changed the title tsc TS5055 - cannot overwrite .d.ts file... TypeScript complains about overwriting .d.ts files that are potentially known outputs Jun 28, 2017
@DanielRosenwasser
Copy link
Member

I still don't think the configuration is appropriate - .d.ts output files are being included in your input files which would be a problem for any project configuration I've ever seen.

@the1mills
Copy link

Daniel, sorry if I wasnt clear ( i am the same person as oresoftware). But two days ago on this thread I clearly stated that the same exact problem occurs when I remove the includes entry altogether from tsconfig.json. This issue does not have to do with the includes property.

@kitsonk
Copy link
Contributor

kitsonk commented Jun 29, 2017

As Daniel stated:

If you remove the include field, then it implicitly includes everything.

Outputting to the same path that your input from is a folly that will cause you endless heartache. How do you expect tsc to determine the difference between a generated .d.ts and one that was intentionally added as an input file? Definition files can be both input and output files.

@ORESoftware
Copy link
Author

@kitsonk this is almost certainly operator error on my part - I have 10+ typescript projects and only this one is suffering from the problem, and I have such a simple configuration, I don't know what's going on yet.

But as far "How do you expect", the answer is simple..

I have an index.ts file + declaration:true
therefore, tsc should be smart enough to know that index.d.ts would be a generated file. There is no way it wouldn't be autogenerated given my setup.

And therein lies my bemusement.

@ORESoftware
Copy link
Author

I updated the original question - I have only one tsconfig.json file in the project and this is barebones and is causing the problem still.

error TS5055: Cannot write file '/Users/alexamil/WebstormProjects/oresoftware/ldap-pool/index.d.ts' because it would overwrite input file.

@ORESoftware
Copy link
Author

here is a link to the project, if you want to see the problem for yourself:

https://github.com/ORESoftware/ldap-pool

@ORESoftware
Copy link
Author

ORESoftware commented Jun 30, 2017

If I do this:

 "include":[
    "*.ts",
    "!*.d.ts"
  ]

then it does not complain - however, I swear I have other projects where I do not need to use that includes property, and they work fine, I am confused.

@hoegge
Copy link

hoegge commented Jul 12, 2017

What version of TSC do you use? When using TSC 1.8 I have the problem below but is gone with version 2.4:

If you generate output in same folder as input you can get the error

TS5055: cannot write file 'file.d.ts' because it would overwrite input file.

This is (off course) because tsc reads also the *.d.ts files. But when I add the option "exclude": [ "**/*.d.ts" ] " to tsconfig.json the error does not go away. That means that tsc does actually not exclude the files I've specified.

@iamchathu
Copy link

I also have this issue. I have turned "declaration": true and it complains about build folder already generated d.ts file when i run again tsc

@the1mills
Copy link

the1mills commented Jul 19, 2019

potentially solved by using the rootDir option:

{
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": "src",
  },
  "include": [
    "src"
  ]
}

@boneskull
Copy link
Contributor

boneskull commented Sep 10, 2019

I'm getting bit by this.

Both cases are valid. I would prefer an option to overwrite them, e.g. overwriteDeclarations.

Meanwhile, find src -name '*.d.ts' -exec rm {} \; && tsc 😝

@boneskull
Copy link
Contributor

(my use case is generating .d.ts files from JavaScript, where those .d.ts files live alongside their .js counterparts; I'm using #32372)

@RomainMuller
Copy link

I am facing a similar issue with the following tsconfig.json:

{
  "compilerOptions": {
    "alwaysStrict": true,
    "charset": "utf-8",
    "composite": true,
    "declaration": true,
    "declarationMap": true,
    "incremental": true,
    "inlineSourceMap": true,
    "lib": ["ES2018"],
    "module": "CommonJS",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "strict": true
  },
  "include": [
    "**/*.ts",
    "**/package.json"
  ]
}

And then whenever I try to do import { version } from './package.json';, the second compilation attempt yields a TS5055 complaining about the package.d.ts that corresponds to package.json.

The reason I think this is incorrect behavior is because it differs to the behavior around .ts files: I can include any pattern of .ts files, and the .d.ts files that correspond to them will not be considered input files... but the .d.ts file corresponding to anything else will be. The difference in treatment is pretty annoying, especially as your typical CI/CD or PR validation build will run on a clean tree (and work), but in a local development environment, the second attempt to build will fail in a surprising way.

@sirreal
Copy link

sirreal commented Mar 7, 2020

I've also run into this issue which I documented here. Quoting:

I'm hitting an issue with is-shallow-equal and I believe it's because the build output is not in a different directory tree from the source files. I've tried a number configurations for tsconfig with no success.

If the generated types exist and the TypeScript build needs to regenerated them, for example source changes or missing .tsbuildinfo, the job will error with:

TS5055: Cannot write file '…/build-types/….d.ts' because it would overwrite input file.

It seems packages/is-shallow-equals/build-types/*.d.ts are being interpreted as source that cannot be overwritten. These are exactly the files we'd like to generate.

To reproduce this issue, do the following:

npm run clean:packages                                ## Clean everything (generated types and tsbuildinfo)
npm run build:package-types                           ## Generate declaration files
echo '// noop' >> packages/is-shallow-equal/index.js  ## Change file to trigger regeneration
npm run build:package-types                           ## !!! ERROR !!!

You'll see the following errors:

error TS5055: Cannot write file '…/gutenberg/packages/is-shallow-equal/build-types/arrays.d.ts' because it would overwrite input file.
error TS5055: Cannot write file '…/gutenberg/packages/is-shallow-equal/build-types/index.d.ts' because it would overwrite input file.
error TS5055: Cannot write file '…/gutenberg/packages/is-shallow-equal/build-types/objects.d.ts' because it would overwrite input file.

The same issue does not occur with other packages where the output directory is isolated from the source directors. For example, a11y does not have the same problem:

npm run clean:packages                        ## Clean everything (generated types and tsbuildinfo)
npm run build:package-types                   ## Generate declaration files
echo '// noop' >> packages/a11y/src/index.js  ## Change file to trigger regeneration
npm run build:package-types                   ## No problem

I've investigated (related issues linked below) and attempted many configuration combinations to get this to work as expected without success. I've gone as far as packages/is-shallow-equals/tsconfig.json as follows:

{
// We wouldn't use this configuration
// It demonstrates different suggestions that have been tried to fix the issue
	"compilerOptions": {
		"allowJs": true,
		"checkJs": true,
		"composite": true,
		"emitDeclarationOnly": true,
		"rootDir": ".",
		"outDir": "build-types",
		"declarationDir": "build-types"
	},
	"exclude": [ "build-types/**/*" ],
	"files": [ "arrays.js", "index.js", "objects.js" ],
	"include": [ "arrays.js", "index.js", "objects.js" ]
}

Apparently related issues:

@leilapearson
Copy link

I ran into this issue too. It seems like some part of the compilation process isn't recognizing that it is inside an excluded directory.

I don't don't see the problem if I do this:

  "exclude": ["**/*.d.ts", "dist", "node_modules"]

I do see the problem if I do this:

  "exclude": ["dist/**/*.d.ts", "dist", "node_modules"]

or this:

  "exclude": ["**/dist/**/*.d.ts", "dist", "node_modules"]

The error occurs despite the fact that the files it is complaining about are clearly inside dist:

error TS5055: Cannot write file '/Users/leila/dev/wip/jest-fp-ts/dist/index.d.ts' because it would overwrite input file.
error TS5055: Cannot write file '/Users/leila/dev/wip/jest-fp-ts/dist/matchers/index.d.ts' because it would overwrite input file.

In my case I have imports set up where src/index.ts imports and re-exports from src/matchers/index.ts which in turn imports and re-exports from src/matchers/eitherMatchers/index.ts.

The first two files are the ones causing the compilation errors. The third file is fine. So it looks like it might be related to how the import / export tree is affecting compilation.

Thought this might be a clue worth mentioning...

@arcsector
Copy link

At the very least there should be a flag that allows you to force an overwrite.

@m-mohr
Copy link

m-mohr commented Oct 22, 2020

	"exclude": [
		"src/*.d.ts",
		"src/builder/*.d.ts"
	],
	"include": [
		"src/*.js",
		"src/builder/*.js"
	],

This also gives the error although I explicitly only include .js and exclude .d.ts. Still complains about input .d.ts overwrite...

@hhanesand
Copy link

hhanesand commented Mar 8, 2021

Hello everyone. I was facing this error today and I found another possible cause for you.

Check if you are importing something like: import { SomeType } from '..'. I was using this in test/some_test.test.ts to import a type declared in ./index.ts. Nothing I changed in the include or exclude options helped.

My fix was to import from ../index instead.

You'll still need to to exclude dist, but I was getting this error regardless. For example :

"files": ["index.ts"],
"include": ["./**/*.ts"],
"exclude": ["node_modules", "dist"]

Can anyone else confirm?

hyochan added a commit to hyochan/dooboo-ui-legacy that referenced this issue Apr 17, 2021
Remove unmaintanable packages, [Table], [PinchZoomSliderModal].

Fix typescript build unable to overwrite issue.
- Related microsoft/TypeScript#16749
hyochan added a commit to hyochan/dooboo-ui-legacy that referenced this issue Apr 18, 2021
Remove unmaintanable packages, [Table], [PinchZoomSliderModal].

Fix typescript build unable to overwrite issue.
- Related microsoft/TypeScript#16749

Migrate to `emotion` to resolve complex typescript issues.
@ArturLuisOliveira
Copy link

I faced the same issue, I've fixed it by ignoring test files and by removing logic from the index file, using it only for exports.

@sheetalkamat
Copy link
Member

You can use --explainFiles to see why the file is in the program.

@silkentrance
Copy link

silkentrance commented Oct 28, 2022

I am having the same issue with vitest + coverage with istanbul. It seems as if vitest is transpiling the code again and trying to replace existing files that have already been generated and are being used as input.

If i add

  "exclude": [
    "dist/*.d.ts"
  ],

to tsconfig.json everything will work just fine.

I am still wondering whether this will impact other workflows, e.g. packaging and publishing to npm...

@ITenthusiasm
Copy link

It would be helpful to get feedback from others on this.

@DanielRosenwasser From the perspective of someone using only JavaScript (via JSDocs in .js files and 1 or 2 .d.ts files when needed), being able to prevent [generated] .d.ts files from being included as inputs is very helpful.

For my use case, I'm working in a monorepo. TypeScript is able to type my entire monorepo with JSDocs. So I don't use the generated .d.ts files at all -- except for npm publishing. Because I'm working with JSDocs, I have a configuration like this:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "allowJs": true,
    "checkJs": true,
    "declaration": true,
    "emitDeclarationOnly": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["./**/*.js"],
  "exclude": ["./index.js", "./**/*.d.ts"]
}

Ideally, for build + release, I would simply say, "Generate the output .d.ts files. Then publish everything in this workspace folder that isn't a test file." Unfortunately, this does not work. Despite my setup, TypeScript still complains about potentially overwriting .d.ts files that are strictly outputs. This is undesirable because of its impact on my build + release process.

During a build + release, it's more convenient for me to say, "Generate (or re-generate) the output .d.ts files. Then publish everything in this workspace folder that isn't a test file" than it is for me to say, "Delete all of the generated .d.ts files. Then re-generate the .d.ts files. Then publish everything in this workspace folder that isn't a test file" or for me to say "Generate the types in a separate build folder. Then copy all .js files to the build folder. Then copy package.json and ...".

In the end, I'm just going to write "prebuild: npm run remove-output-d-ts-files" and "build: tsc" as npm scripts for the build step. But if developers have to do this, it's a sign that they know what's an input and what's an output. To me, it would make sense if TypeScript was updated so that this extra inconvenient step wouldn't be necessary anymore.

@ITenthusiasm
Copy link

ITenthusiasm commented Oct 6, 2023

.d.ts output files are being included in your input files which would be a problem for any project configuration I've ever seen.

Agree that output .d.ts files definitely should not be included as inputs. I would just like to be able to specify what should be excluded by using tsconfig.json. boneskull hit the nail on the head with a small comment.

@SalamandraDevs
Copy link

I was facing this same error for two reasons:

  1. I putted a my-module.d.ts file with a module declaration (declare module 'my-module') inside the src/ folder trying to find a solution for another problem.
  2. I linked my-module types to node_modules/@types/my-module with a symlink.

Delete both solved the problem.

@fregante
Copy link

Solution

In short, this:

{
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "dist",
  }
}

The solution here is to define both rootDir and outDir folders and **make sure that they're not inside one another.

Any config other other than this will eventually cause this error.

Why

The error is not clear enough, but it happens because TypeScript is processing all supported files in a folder, then it outputs them in the same folder. Some of these files (d.ts) fall back into the "files to process" list, so when it tries to, again, write the file in the same spot, it complains that it's the same as the input file.

This is not a bug.

However deciphering TypeScript errors is near impossible to anyone who doesn't spend hours trying to figure out what TypeScript is doing. It could have been:

error TS5055: The input file './blah/index.d.ts' is set to be output at the same path because outDir is ".". https://LINK-TO-DOCS-WHERE-THIS-IS-EXPLAINED-FURTHER.

@12joan
Copy link

12joan commented Apr 26, 2025

I'm getting this error in one of my Yarn workspaces despite having a separate rootDir and outDir. Other worspaces with identical configs work fine. Strangely, the error stops happening if I change outDir from dist to anything else, like dist2.

Edit: It seems to happen when I use the same directory as outDir for the types option in the affected workspace's package.json file. If I change outDir to dist2 the error disappears, but if I change types from dist/index.d.ts to dist2/index.d.ts it comes back. Still not sure why only this workspace is affected.

Edit 2: It turned out to be because some random file in @untitled/frontend was trying to import from @untitled/frontend. I wish TypeScript would produce an error message that would have helped me discover this.

packages/frontend/tsconfig.json
{
  "extends": "../../configs/tsconfig.json",
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "dist",
    "composite": true,
    "jsx": "react-jsx",
    "jsxImportSource": "@emotion/react",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src"],
  "references": [
    { "path": "../shared" },
    { "path": "../file-system" }
  ]
}
configs/tsconfig.json
{
  "compilerOptions": {
    "target": "es2017",
    "module": "esnext",
    "moduleResolution": "bundler",
    "lib": ["dom", "es2019"],
    "types": ["@types/jest", "jest-extended"],
    "strict": true,
    "alwaysStrict": true,
    "strictFunctionTypes": true,
    "strictNullChecks": true,
    "strictPropertyInitialization": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noFallthroughCasesInSwitch": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "downlevelIteration": true,
    "declaration": true,
    "pretty": true
  }
}
packages/frontend/package.json
{
  "name": "@untitled/frontend",
  "private": true,
  "version": "1.0.0",
  "type": "module",
  "license": "MIT",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "dependencies": {
    "@untitled/file-system": "workspace:^",
    "@untitled/shared": "workspace:^"
  },
  "packageManager": "[email protected]"
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests