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
.js, .jsx and .json filesThanks, 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. loopback@^3) requires the model and implementation files to have the same name. 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.