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

Allow tsconfig.yaml in addition to tsconfig.json #40027

Open
5 tasks done
dradetsky opened this issue Aug 13, 2020 · 28 comments
Open
5 tasks done

Allow tsconfig.yaml in addition to tsconfig.json #40027

dradetsky opened this issue Aug 13, 2020 · 28 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

@dradetsky
Copy link

dradetsky commented Aug 13, 2020

Search Terms

yaml
tsconfig format

Suggestion

I suggest allowing the tsconfig.json file to be replaced with tsconfig.yaml.

This would be implemented by simply converting the yaml to json and passing it to whatever method currently interprets the contents of tsconfig.json.

Additionally, I would propose that the presence of both a tsconfig.json and a tsconfig.yaml file in the root of a project is an error.

Use Cases

Like #30400 (which I found originally), I'd like to add comments to my project config. Also, yaml is just a nicer format for something intended to be edited by a human.

I have created this simply because #30400 (which called for adding tsconfig.js) was closed for reasons which do not apply to yaml. So I thought there should be an open issue. You can always close it for other reasons, right?

Examples

following the example in the handbook

% cat example.json
{
  "compilerOptions": {
    "module": "commonjs",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "sourceMap": true
  },
  "files": [
    "core.ts",
    "sys.ts",
    "types.ts",
    "scanner.ts",
    "parser.ts",
    "utilities.ts",
    "binder.ts",
    "checker.ts",
    "emitter.ts",
    "program.ts",
    "commandLineParser.ts",
    "tsc.ts",
    "diagnosticInformationMap.generated.ts"
  ]
}
% cat example.yaml
compilerOptions:
  module: commonjs
  noImplicitAny: true
  removeComments: true
  preserveConstEnums: true
  sourceMap: true
files:
  - core.ts
  - sys.ts
  - types.ts
  - scanner.ts
  - parser.ts
  - utilities.ts
  - binder.ts
  - checker.ts
  - emitter.ts
  - program.ts
  - commandLineParser.ts
  - tsc.ts
  - diagnosticInformationMap.generated.ts

Checklist

I'M PRETTY SURE 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. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.
@dradetsky
Copy link
Author

dradetsky commented Aug 13, 2020

Additionally, addressing the question of "What shortcomings exist with current approaches?"

I did note that it was possible to add comments to the tsconfig.json. However, from a human-interface perspective, this is bad. People who know how JSON works know that it doesn't generally support comments. So they won't try to add comments to this file even if they want to. And people who don't yet know how JSON works will see examples and try to put comments in their package.json files and find that it doesn't work and be confused.

Also, maintaining a JSON parser which supports comments is work which is probably better avoided (although I recognize that dropping support for comments in tsconfig.json may not be feasible). If you want to comment your config file, you can just use YAML. You don't need to add one more unnamed, unstandardized way of having JSON-but-with-comments. I mean, now that you have you probably have to support it for some time, but pushing the existing userbase towards doing this by just using YAML would probably be a good thing.

@RyanCavanaugh RyanCavanaugh 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 Aug 17, 2020
@dradetsky
Copy link
Author

@RyanCavanaugh is there a standard for "Received Enough Feedback" or is it just basically "Core devs feel that number of positive respondents is sufficient given the (expected) complexity of the change?"

I would note that @alexmiddeleer arguably counts as a positive respondent.

@EfstathiadisD
Copy link

Please implement this. JSON is not a proper format, for configuration. See eslint and prettier. They both accept yaml formats. If Typescript accepted that, it would be a huge step forward. JSON, should never be the default configuration otpion. It is one more bad habit, that came from node.

@RyanCavanaugh
Copy link
Member

is there a standard for "Received Enough Feedback" or is it just basically "Core devs feel that number of positive respondents is sufficient given the (expected) complexity of the change?"

There's no concrete standard. The number of positive respondents is one factor, but we're also considering the qualitative aspects of the verbatim comments -- e.g., are people completely blocked, are they inconvenienced, are they feeling a sense of technical friction, are they resorting to difficult workarounds, etc..

@dradetsky
Copy link
Author

@RyanCavanaugh checking in. How are core typescript devs currently feeling about the level of feedback so far?

@montyz
Copy link

montyz commented Dec 24, 2020

Yaml for allowing comments would make my life easier, and help my coworkers too.

@RyanCavanaugh
Copy link
Member

Yaml for allowing comments would make my life easier

Just so you know, you can already write comments in tsconfig.json files

@dradetsky
Copy link
Author

@RyanCavanaugh isn't explaining that to people over and over fun?

@RyanCavanaugh
Copy link
Member

It pays the bills 🙃

@jcayzac
Copy link

jcayzac commented Feb 12, 2021

YAML is a better configuration format than JSON for the same reasons JSON is better than XML: by forcing humans to read noisy input, mistakes are more easily made; by forcing humans to decorate content with extra syntax, copy-paste happens more often and mistakes are more easily made.

@sequencerr
Copy link

YAML syntax is prettier for me. Hope this will be realized.

@jcayzac
Copy link

jcayzac commented Jul 5, 2021

By the way, I think it's pretty obvious to anybody who has seriously worked with YAML, but maybe it's useful to state that it's YAML 1.2 that should be supported, not the legacy, ambiguous, error-prone YAML 1.1 spec.

@kaaax0815
Copy link

Is this in development? Because I think it would be a great addition

@jacobq
Copy link

jacobq commented Sep 10, 2021

FWIW, I use tsc to generate JS for node using native ESM (no babel, no webpack, etc.), and in order to get module path mapping to work I rely on being able to read tsconfig.json (in a custom loader) via the simple JSON.parse('tsconfig.json').

While I like YAML, I also like keeping things simple. If we have to support more formats then anything reading content from tsconfig is going to need another layer of abstraction / more code. It wouldn't be a big deal if YAML parse/stringify functions were built into the standard (ES20xx), but presently they are not, so this would likely mean adding yet another library to devDependencies. If tsconfig can be specified via multiple languages/formats then it should really provide its own type/interface and some kind of parseTsConfig() function, but I think that's making things more complex than they need to be. If you really want to use YAML, why not just add a step to the build that generates a JSON from the YAML? (e.g. https://www.npmjs.com/package/yamljs#command-line-tools)

@ChrisCrossCrash
Copy link

ChrisCrossCrash commented Sep 13, 2021

@jacobq Thanks for the yamljs recommendation.

Here's how I used it:

  1. npm install --save-dev yamljs to install the yaml-to-json converter.
  2. json2yaml tsconfig.json > tsconfig.yaml to convert the existing TS configuration to yaml (this is a one-time step).
  3. I've modified my package.json with the following changes:
{
  "scripts": {
    "build-configs": "yaml2json . --pretty --save",
    "develop": "npm run build-configs && gatsby develop"
  }
}

build-configs converts all the .yaml files in my root project directory into .json files. I've done it this way so that it also converts my other configs. For example: cypress.yaml also gets converted to cypress.json

Now I can edit the tsconfig.yaml, and it automatically gets converted to tsconfig.json when I execute npm run develop.

Pros

  • Automatic conversion of tsconfig.yaml to tsconfig.json before running an npm script.
  • At least in my IDE (PyCharm Professional), code hinting works on the tsconfig.yaml file. I can hover over the config keys and PyCharm gives me popup descriptions (see image below). Auto-completion also works. Unfortunately, the same cannot be said for my only other config, cypress.yaml. PyCharm doesn't give hints like it does in cypress.json (If somebody knows how to fix this, please let me know).
    image

Cons

  • New dev dependency yamljs in my project
  • Having two config files is confusing for people who aren't familiar with your project. You can't even add a comment to the top of the json file saying // don't edit this. Edit tsconfig.yaml instead, since json doesn't support comments, and even if it did, it would be overwritten.
  • This adds a bit of weird complexity to the project in order to do something pretty trivial.

For me, the cons outweigh the pros. The deal-breaker for me was how my IDE doesn't give me hints in my non-tsconfig.yaml config files.

@jacobq
Copy link

jacobq commented Sep 13, 2021

Sorry if this comment is veering off-topic, but I appreciated your (@ChrisCrossCrash) thorough note taking for other interested parties so wanted to respond to your question.

  • At least in my IDE (PyCharm Professional), code hinting works on the tsconfig.yaml file. I can hover over the config keys and PyCharm gives me popup descriptions (see image below). Auto-completion also works. Unfortunately, the same cannot be said for my only other config, cypress.yaml. PyCharm doesn't give hints like it does in cypress.json (If somebody knows how to fix this, please let me know).

These hints (hover, auto-completion, highlighting, and whatnot) are generally made possible via JSON Schema definitions mapped to those files. IIRC, JetBrains IDEs uses the public schemastore.org catalog; see
https://www.jetbrains.com/help/pycharm/json.html#ws_json_using_schemas & https://brunopaz.dev/blog/how-to-create-your-own-auto-completion-for-json-and-yaml-files-on-vs-code-with-the-help-of-json-schema

  • New dev dependency yamljs in my project
  • Having two config files is confusing for people who aren't familiar with your project. You can't even add a comment to the top of the json file saying // don't edit this. Edit tsconfig.yaml instead, since json doesn't support comments, and even if it did, it would be overwritten.
  • This adds a bit of weird complexity to the project in order to do something pretty trivial.

I would argue that this complexity is the cost of the feature. It can either be put into your projects (annoying/inelegant) or upstream (still inelegant but no longer so annoying due to being practically invisible), but in any case it must exist somewhere. More choices (JSON/YAML/TOML/INI/XML/fill-in-the-blank) + more human-friendliness is nice but not free.

Another solution path to consider would be to make an "add-on" module/lib/tool that contains this functionality and can be dropped into your projects -- keeping the functionality isolated without bloating the core upstream package. How that's done depends a lot on your specific project/build arrangement, of course. One way would be to make a @my-scope/typescript package that basically "replaces" typescript in your projects but passes everything through to it except first does YAML->JSON (and perhaps keeps that JSON file out of sight / version control or deletes it after compilation). It might even make sense to do this as an IDE plugin instead.

If the core team believes that the value of adding a feature like this is worth the cost (effort, maintenance, doc, support, ...) that's all fine and good. In my experience, though, I set up tsconfig.json for a project then practically forget that it's even there as I get busy developing the app itself, so I personally wouldn't want to spend my time working on it.

@jcayzac
Copy link

jcayzac commented Sep 15, 2021

While I like YAML, I also like keeping things simple. If we have to support more formats then anything reading content from tsconfig is going to need another layer of abstraction / more code.

This is typically something that should be abstracted for you by an import.meta.

@morganbarrett
Copy link

fact: most devs have ocd
solution: .typescriptrc.{json|ya?ml}

but yeah, I would love to be able to use yaml for tsconfig

@benedictjohannes
Copy link

benedictjohannes commented Dec 25, 2021

@RyanCavanaugh I would offer my technical reasoning for why allowing the easier to read and write YAML is a logically sound.

Firstly, every programming language that I know does not support the commented JSON format. Not even nodeJS, try this: let tsConfig = require('tsconfig.json').
Importing a package to parse it might, but why maintain the same file extension and cause confusion?

It pays the bills 🙃

So does paying someone to compare documents, but I believe there's a great reason Microsoft created the "track changes" feature in Microsoft Word.

Secondly, in defense of NPM (and other package managers) using package.json and not supporting any other is quite obvious: npm needs to be able to (programmatically) alter the contents of package.json.
ESLint, Prettier, Webpack expect the config files to be hand-written, and does not offer to alter the configs in any way. There's no such prettier --alter-config --enable-pragma afterall.
But, there's no tsc --alter-config --set-jsx react to be seen either. So, apart of the effort needed, any reason for sticking with only tsconfig.json?

I'm quite sure the community would be happy to help with PR that helps in the effort part, as long as it won't be rejected for reasons other than it doesn't work or breaks something.

@NatoBoram
Copy link

NatoBoram commented Jan 20, 2022

Additionally, putting comments in .json files, while supported it's by some specs-breaking programs, might work sometimes, it's factually wrong. The file should've been .jsonc in the first place so that it's understood by every editor and .json readers and displays as a .jsonc file instead of having to hard-code or configure the tsconfig.json files as being .jsonc files.

image

While Microsoft have already taken the stance in the past that they don't care about this issue, I think it would be better if a .yaml file was used so at least it would be not implementation-dependent and actually respect at least one standard.

The problem this issue addresses is that tsconfig.json does not respect any standards at all. It's a .jsonc file with a .json extension, which breaks every non-Microsoft products because people outside of Microsoft have standards.

@gotjoshua
Copy link

I hope that it is clear that this issue is not only about the comments.
Also it is a request to also support y?aml files, not to require them instead of json.

There is significant precedence as noted above (eslint and prettier)

Furthermore

Vite also directly supports TS config files. You can use vite.config.ts with the defineConfig helper as well.

which, quite frankly, could be seen as embarrassing that typescript itself doesn't.

@woutermont
Copy link

I'll bump this once more, because it would really improve developer experience when we'd be able to write TS config in YAML ❤️

  • 🗒️ My editor would be happy, since I would no longer have to hack into allowing JSON comments specifically for tsconfig files.
  • 👀 My eyes would be happy, since they would no longer have to strain to find configuration values between all the structural noise.
  • 🖐️ My fingers/wrists would be happy, since they would no longer have to reach for the brackets, quotes and comma's all the time.
  • 🧠 My OCD brain would be happy, since most of my projects would then be only one (Jest) step away from having all configuration in YAML.
  • 👨‍💼 My boss would be happy, since I would be a more productive and enjoyable colleague because of all the above.

@cobaltp
Copy link

cobaltp commented Jan 30, 2023

I totally agree with this. Except for this one, all of my other settings file are written in yaml. It's more clear and human readable.

@matthewjh
Copy link

Yes please. Since moving to PNPM, we switched from package.json to package.yaml for improved readability and ergonomics (including, but not limited to comments). Would love to do the same for our tsconfigs.

@bennidi
Copy link

bennidi commented Sep 14, 2023

Just to add another argument in favor of yaml: The configuration of typescript in combination with the other parts of tooling like babel, metro, vite, webpack etc. is horribly complex and confusing. This is a VERY BIG DOWNSIDE of the freedom of the whole JS centred ecosystem. Every tool evolves independently and the more successful ones become kind of standard (without proper process of standarization).

As a developer I have spent countless hours trying to figure out the correct configuration for my toolstack. A very painful process. One reason for this being so difficult is because developers can not put comments in JSON and as such can not embed the contextual information that is actually the reason for a certain config option to be set this way or another. Period! It is freaking annoying and a painful limitation and drawback of JSON format when used for actual coding (not just data).

I think that support yaml as format for tsconfig would mean a very big improvement to the future of the TS ecosystem.
It is also a relatively low handing fruit because YAML parsers are available and it is just syntax and not semantics that will be added. It is also backward compatible because YAML will be added and not used to replace JSON.

So, actually...why the resistance to ship this change?

@jasongitmail
Copy link

Would rather see ts.config.js to go alongside the new eslint.config.js+ prettier.config.js, playwright.config.js, vite.config.js, tailwind.config.js, etc. Omg, so many. But really, can import from a global config using ES6, comments, consistency... 😝

@cdaringe
Copy link

I support something like this request, purely on the merits of the following observation for tsconfig:

JSON != JSONC

https://code.visualstudio.com/docs/languages/json#_json-with-comments

I have zero qualms with JSON. However, labeling a file as JSON immediately invokes expectations of its content.

I have been using tsconfig.json happily for years without issue.

Today, this naming misnomer caused a demonstrably competent, smart, senior engineer to make a smart, but incorrect assumption. A formatter update started appending commas to final items in arrays in our tsconfig. "That's not valid JSON" they noticed, which prompted a bunch of activity to protect our automated builds/release pipelines... which was all not necessary, because of course, tsconfig.json is not json. I've observed peer developers on more than one occasion try and read/parse tsconfig.json with JSON.parse, etc unsuccessfully.

By marking a non-json file as json, developer friction has observably ensued. It's not a huge deal, but it's completely avoidable for an enormous population of users.

Dropping tsconfig.json support is a non-starter (I presume all parties are aligned there). Going forward, however, I advocate the default config file extension should be honest about its format.

tsconfig.jsonc or tsconfig.yml would be be better defaults, as there is no ambiguity.

@HolgerJeromin
Copy link
Contributor

Many web tools use yml, but this is perhaps not the best format.
https://ruudvanasseldonk.com/2023/01/11/the-yaml-document-from-hell

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