TypeScript: TS5055 error while import a non relative json module with resolveJsonModule option

TypeScript Version: 3.0.0-dev.20180605

Search Terms: TS5055 resolveJsonModule

Code

tsjson> find . . ./main.ts ./json ./json/myjson.json ./tsconfig.json ./src ./src/test.ts

tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "baseUrl": "./",

    "resolveJsonModule": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,


    "strict": true,
    "noEmitOnError": true
  },
  "include": [
    "main.ts",
    "src",
    "json"
  ],
  "exclude": [
    "node_modules"
  ]
}

main.ts:

import "test";

src/test.ts:

import myjson from "json/myjson.json";

console.log('hello world!', myjson.message);
export {}

json/myjson.json:

{
    "message": "to be continue..."
}

Expected behavior: compile successful

Actual behavior: tsjson> tsc error TS5055: Cannot write file ‘*************/tsjson/json/myjson.json’ because it would overwrite input file.

Playground Link:

Related Issues:

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 7
  • Comments: 31 (3 by maintainers)

Commits related to this issue

Most upvoted comments

Another common use-case.

Let’s say I have the following project structure:

package.json
src/*.ts
dist/*.js

If I specify include: src, outDir: dist and resolveJsonModule: true, and import the package.json version with import { version } from '../package.json', then suddenly my dist directory looks like this:

dist/package.json
dist/src/*.js

Even if that’s “working as intended”, I think that might surprise a lot of people.

Can this be re-opened and the Working as Intended label get removed?

If it is really “working as intended”, I think there should be some documentation that this feature only works in conjunction with the outDir option.

It almost seems like it is not intended to be used for common use-cases like:

import { version } from './package.json'

I guess it would be fine if you could somehow ignore TS5055, but // @ts-ignore has no power here so people using bare-bones tsc are out of luck…

@mhegazy

the compiler when resolving a .json file will read it and write it again

If the outDir is different, that makes sense. But if not, then why try to overwrite it? .json files are closer to being treated like static assets than javascript, so there isn’t a ‘build artefact’ equivalent here.

we should be able to tell tsc to skip outputting json files when nedded with "exclude": "folderWithJson/*"

I was surprised to find this doesn’t work already. I’ve had to revert to using require instead of import to load a json due to this bug. I can’t have the json copied to the outDir as it’s not under my rootDir in the project, it changes the outDir structure as @MarkTiedemann shows above, and I get a TS6059 error.

When using include in tsconfig.json, if the json file is not explicitly included with include, or is explicitly listed in exclude, the json should not be copied to outDir.

Just hit this as well. The fact that the outDir option has to be set for resolveJsonModule to work properly seems like a hack. My use case is a JSON file containing test fixtures which is imported from a test suite. Now my choice is to either output test/ to something like dist-test/ (as src/ would have to be output to dist/) or simply disable well-typed JSON imports, and I’m a little bummed out about the latter being preferable.

If you follow this common use-case, then I have a workaround for importing package.json without mangling the output directory.

I am able to convert this problematic statement:

import pkg from '../package.json'

into

const pkg = require('../package.json')

Previously, I had used require(require.resolve('../package.json')). I have now found that extra call to be unnecessary. I don’t remember why we needed require.resolve, but that at the time our program made some complaints.

One side-effect is you lose access to static type-checking as the compiler doesn’t know where the dynamically imported module is from at compile-time.

Having to explicitly set one option like outDir to enable other option like resolveJsonModule is not (in my opinion) something that should be marked as working as intended. There are many scenarios where, you can’t have or do not want to have different outDir. For example in NativeScript the outDir is exactly the same which is resulting in that resolveJsonModule to be unusable with the latest TypeScript version.

I thing that the options should be decoupled - we shouldn’t have to mandatory set one option to have another in a working state. Not to mention that you can still set the outDir` to the very same folder and cause the very same bug to reappear (which is creating a third rule - do not set outDir as the project dir…)

@mhegazy If there is no outDir specified, why should the .json file be duplicated? It’s a static resource… is there a way to do this without needing outDir?

this issue should not be closed as there is still people struggling with this. Is not fixed and while working with visual studio is very annoying

Before I found this issue, I also left a comment on #24744 which is still open (I hadn’t realized this issue is closed and marked fixed, so this discussion will likely go unnoticed).

the compiler when resolving a .json file will read it and write it again. so you really want to have --outDir option set to avoid the compiler overwriting you input file.

we should be able to tell tsc to skip outputting json files when nedded with "exclude": "folderWithJson/*"