Typescript: JSON files generate declarations

Created on 28 Oct 2019  ·  10Comments  ·  Source: microsoft/TypeScript

TypeScript Version: 3.8.0-dev.20191026

Search Terms: json, declarations

Code

// tsconfig.json
{
  "include": ["src/**/*", "src/**/*.json"],
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "dist",
    "resolveJsonModule": true,
    "declaration": true
  }
}
// src/test.json
{}

Expected behavior:

dist
└── test.json

(same as on v3.6.4)

Actual behavior:

dist
├── test.d.ts
└── test.json

Playground Link:

Related Issues: #34676

Bug

All 10 comments

32372 enables declaration for .js, .jsx and .json files

Thanks, I haven't noticed that it enabled it for .json files as well. Shouldn't it be named test.json.d.ts instead of test.d.ts though? Since json files can be imported only with extension, generated declarations would always reference it as ./test.json, which wouldn't find test.d.ts. Another solution there would be to trim .json extension for declaration resolution, like .js, but there is an another problem it causes - it's not allowed to have .ts and .json files with the same name anymore.

Hmm, Node at least will load .json even without an extension:
https://nodejs.org/api/modules.html#modules_all_together

LOAD_AS_FILE(X)
1. If X is a file, load X as JavaScript text.  STOP
2. If X.js is a file, load X.js as JavaScript text.  STOP
3. If X.json is a file, parse X.json to a JavaScript Object.  STOP
4. If X.node is a file, load X.node as binary addon.  STOP

Yah, our filename generation assumes the same extension stripping behavior on import for all extensions. I'm... Conflicted? On generating a obj.json.d.ts instead of obj.d.ts. I don't want to special case it. In theory, it shouldn't be treated any differently than .ts or .tsx or any other supported extension; but our implementation of json file imports doesn't seem to have the same resolution behaviors that normal imports do (which is odd, since .json is lIke any other supported extension in node). Thing is, any non-technical reason one has to justify generating a obj.json.d.ts also justifies generating file.ts.d.ts and the like (as you're equally capable of having .ts and .js and .tsx and .jsx files of the same name side-by-side)... And I _really_ don't think we wanted to start doing that. Because of that, I'm _inclined_ to want to introduce extension stripping declaration file lookup for json imports, just like what other extensions do, instead... (Despite knowing that yes, it prevents you from having multiple files with the same name in the same place - I don't think it's been a problem for .tsx and .ts, so I'd hope people can work with .json the same way)

Point against file.ts.d.ts specifically: TS actually errors on imports ending in .ts.

@weswigham Maybe at least there should be a flag to disable emitting declaration files for *.json?

I'm in a Catch 22 situation here, and would really appreciate a way out - e.g., a boolean flag to turn off declaration output for json - e.g., declarationJson:

  • declaration: false for my projects that use JSON is not an option, because Composite projects may not disable declaration emit. Also, I want the types.
  • Renaming the JSON is not an option, because the framework (loopback@^3) requires the model and implementation files to have the same name.
  • Setting resolveJsonModule: false will require to re-introduce the Gulp hell I have now been able to get out of to move JSON files to the dist directory.

@weswigham - I understand there are many considerations to take into account here, but some way to deal with this issue would be nice.

Am I correct in thinking this also poses a problem in projects that don't specify an outDir? For some foo.json a foo.d.ts get's generated. Unlike .d.ts files generated from .ts files, this new foo.d.ts is included during compilation. Generating an error like this:

error TS5055: Cannot write file '/foo/bar/package/lib/foo.d.ts' because it would overwrite input file.

It's the same thing the happens when you have both a foo.ts and a foo.tsx or foo.js in the same place in a build, yes.

AFAIK this was already done in #36066, so I'm closing this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

siddjain picture siddjain  ·  3Comments

bgrieder picture bgrieder  ·  3Comments

CyrusNajmabadi picture CyrusNajmabadi  ·  3Comments

jbondc picture jbondc  ·  3Comments

dlaberge picture dlaberge  ·  3Comments