Skip to content
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

json files should be usable in .d.ts files without breaking things #24744

Open
4 tasks done
jpike88 opened this issue Jun 7, 2018 · 9 comments
Open
4 tasks done

json files should be usable in .d.ts files without breaking things #24744

jpike88 opened this issue Jun 7, 2018 · 9 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

@jpike88
Copy link

jpike88 commented Jun 7, 2018

Search Terms

resolveJsonModule import definition

Suggestion

As a .json file is a static resource, it should be able to be referenced in a global.d.ts file for example without that file being automatically treated as a module. The reason for this is that a .json file may be used to simply enforce valid translation keys, and you shouldn't need to suck the whole .json file into the transpilation process to do that.

Use Cases

Example:

import translations from "../assets/translations/en-AU.json"
type $translate = {
    instant: (translationKey: keyof typeof translations) => string,
    use: Function,
    proposedLanguage: Function
}

The downside of the current method again is that the translations file is output in the transpilation process, which is wasteful if the file is large.

What the above code snippet is trying to achieve, should be allowed in a .d.ts file without breaking global declaration functionality.

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript / JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. new expression-level syntax)
@mhegazy mhegazy added Suggestion An idea for TypeScript Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature labels Jun 7, 2018
@vekexasia
Copy link

Unfortunately I've the very same issue on a project of mine where the json is imported into the "dist" folder breaking seveal things.

@AlCalzone
Copy link
Contributor

I just ran into the same issue. Given the following directory structure:

build/  - The compiler output ends up here
src/    - The sources reside here
  file1.ts
  file2.ts
  ... and so on
somejsonfile.json - The file I'm trying to include. It is guaranteed to be there in the final module

Compiling the source code results in this structure if I don't reference somejsonfile.json from source code:

build/  - The compiler output ends up here
  file1.js
  file1.d.ts
  ... and so on
src/    - The sources reside here
  file1.ts
  file2.ts
  ... and so on
somejsonfile.json - The file I'm trying to include. It is guaranteed to be there in the final module

If I do import from somejsonfile.json, instead of just compiling from src to build, the structure is shifted:

build/  - The compiler output ends up here
  src/  - This is extraneous!
    file1.js
    file1.d.ts
    ... and so on
  somejsonfile.json  - This is just copied from the root dir.
src/    - The sources reside here
  file1.ts
  file2.ts
  ... and so on
somejsonfile.json

which results in duplication of the json file and an unnecessary src directory inside build.

Unfortunately, this means that resolveJsonModule is unusable for what I'm trying to do - that is reading strongly typed config data from a json file.

@mhegazy Is this the kind of feedback you're looking for?

@oryandunn
Copy link

I just ran into this same issue myself.

As @AlCalzone shows above, when importing a json and using the resolveJsonModule flag in your tsconfig.json, tsc will copy that json into the build directory. If you're using the "outDir": "./build" and "rootDir": "./src" options, you will also get an error:

error TS6059: File '.../somejsonfile.json' is not under 'rootDir' '.../src'. 'rootDir' is expected to contain all source files.

It's quite strange because it issues an error, but then carries on with the build, implicitly setting rootDir up level(s) until it finds a common root (in this example, it's up one level).

I've attempted to skirt this issue by setting the include property in tsconfig.json:

"include" : [
    "src/**/*"
]

or by exclude:

"exclude": [
    "somejsonfile.json"
]

or by both

"include": [
    "src/**/*"
],
"exclude": [
    "somejsonfile.json"
]

but in all cases, I get the TS6059 error and end up with the build directory containing a src folder and the somejsonfile.json file.

As of now, I've had to revert to using const jsondata = require("somejsonfile.json");. I'd like to be able to use resolveJsonModule and import, but as of now I'm unable to.

@AlCalzone
Copy link
Contributor

As of now, I've had to revert to using const jsondata = require("somejsonfile.json");. I'd like to be able to use resolveJsonModule and import, but as of now I'm unable to.

I actually only want to use a type that is derived from the contents of the json file, not the contents of the file itself. I feel there should be a way to rely on json files without including them in the build output.

@AlCalzone
Copy link
Contributor

Over the weekend I ran into another issue, where having type checking based on the types from a json config file would have saved me some headaches.

A numeric variable was incorrectly set as a string in the web frontend while the backend was expecting a number. Both have access to the json file at compile time.

@AlCalzone
Copy link
Contributor

AlCalzone commented Nov 13, 2018

My current workaround to get static typechecking based on json contents without file duplication:

  1. Have a symlink from the source directory to the json file in question
  2. Import the symlinked json file in the (.d).ts files.
  3. Delete the json file from the build output in the postbuild step.

This works for me, but I refuse to believe this feature is working as intended.

Edit: checking out a repo with symlinks is problematic on windows though...
So the current workaround is just using the json file where it resides and a postbuild step:

"postbuild": "cpx build/src/**/*.* build && rimraf build/src && rimraf build/config.json",

@noel-schenk
Copy link

How about another parameter. "compileJsonModule":true|false
Current code would still work and for future implementations devs would have the option to keep the strucutre.

@Bessonov
Copy link

Bessonov commented Sep 14, 2019

Have simillar issue:

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

program
	.version(version)
	.parse(process.argv)
error TS6059: File '/home/vagrant/workspace/package.json' is not under 'rootDir' '/home/vagrant/workspace/src'. 'rootDir' is expected to contain all source files.

@CMCDragonkai
Copy link

I find it interesting that even if TS2732 error occurs, the tsc compiler just continues. Surely there must be a way to make it not bother compiling the JSON file, so that we can reference things outside the outDir.

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

8 participants