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

tsconfig.json - extends property should handle more than one config paths #42386

Closed
5 tasks done
RamoFX opened this issue Jan 17, 2021 · 17 comments
Closed
5 tasks done

tsconfig.json - extends property should handle more than one config paths #42386

RamoFX opened this issue Jan 17, 2021 · 17 comments
Labels
Duplicate An existing issue was already created

Comments

@RamoFX
Copy link

RamoFX commented Jan 17, 2021

Suggestion - tsconfig.json - extends more than one configs

🔍 Search Terms

  • tsconfig multiple extends config
  • TS5024: Compiler option 'extends' requires a value of type string
  • tsconfig extends
  • tsconfig extends multiple
  • tsconfig extends string array

✅ Viability 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. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of [TypeScript's Design Goals]

⭐ Suggestion

A tsconfig.json have compilerOptions, include, files and extends, I'll be describing the extends feature suggestion.

It only takes a string type which is a path to the tsconfig.json, but it would be useful to take more paths.

So extends property should be able to process one or more paths.

📃 Motivating Example

Below I attached an example code image of what this can be helpful for. The image shown tree of 7 config parts in the left side and the code example on the right of extends them together.

image

💻 Use Cases

What do you want to use this for?

It will give a lot of possibilities.
For example, you will be able to make one configs directory and mixing them via extends for best config and fast project configuration.

What shortcomings exist with current approaches?

Inconvenience: you need to chain them one by one, which is of course not the best practice. If you will add another one and next ot it will be another 10 files then it takes some time to make it works again.

What workarounds are you using in the meantime?

Chaining them (b extends a, c extends b, etc.).
Or you can even make some script that generates certain config from other parts.
Or maybe some package that includes all files into one.

@RamoFX RamoFX changed the title tsconfig.json - extends more than one configs tsconfig.json - extends property should handle more than one config paths Jan 17, 2021
@MartinJohns
Copy link
Contributor

Related / duplicate: #29118. Used search terms: extends tsconfig in:title

@RamoFX
Copy link
Author

RamoFX commented Jan 17, 2021

Oh, you are right. Sorry for that.

@RamoFX RamoFX closed this as completed Jan 17, 2021
@RamoFX
Copy link
Author

RamoFX commented Jan 17, 2021

The issue that you provided was opened on Dec 21, 2018 and there is no response from contributors and finally it was closed on Aug 22, 2020.

Is this feature possible? I don't think it is that hard to develop / little bit refactor.

@RamoFX RamoFX reopened this Jan 17, 2021
@gurunars
Copy link

gurunars commented Jan 18, 2021

I would rather say that multiple inheritance is bad even in the context of tsconfigs.

I personally tend to generate tsconfig files before performing typescript builds. This allows me to create quite sophisticated pipelines. IMO, tsconfigs' syntax should be as blunt and featureless as possible and any extension and re-usability should be achieved at a meta level.

@RamoFX
Copy link
Author

RamoFX commented Jan 18, 2021

@gurunars
I would rather say that multiple inheritance is bad even in the context of tsconfigs.

I personally tend to generate tsconfig files before performing typescript builds. This allows me to create quite sophisticated pipelines. IMO, tsconfigs' syntax should be as blunt and featureless as possible and any extension and re-usability should be achieved at a meta level.

Hi! Thanks for your advice, I'll consider it in the future.

@RyanCavanaugh
Copy link
Member

I've reopened #29118

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Jan 21, 2021
@mutech
Copy link

mutech commented Jan 21, 2021

I would rather say that multiple inheritance is bad even in the context of tsconfigs.

I personally tend to generate tsconfig files before performing typescript builds. This allows me to create quite sophisticated pipelines. IMO, tsconfigs' syntax should be as blunt and featureless as possible and any extension and re-usability should be achieved at a meta level.

The same argument would hold for single inheritance. The proposition adds no features that you could not achieve with single inheritance, except for providing a better composability.

I agree that the additional complexity always adds a risk. However, the complexity of build pipelines is already suffocating and adding to that complexity is no less risky or painful. The solution for most developers who are not working on an industrial scale is typically Copy & Paste, painful comparisons of different tsconfigs, painful research in the docs to remember conflicting settings or their precise semantics.

To me, the current limitation looks like the complexity is already there, we just deny ourselves to benefit from its existence.

@mutech
Copy link

mutech commented Jan 21, 2021

I've reopened #29118

I think it's more interesting to follow this issue, since there are conflicting opinions here.

@RamoFX RamoFX closed this as completed Jan 21, 2021
@mutech
Copy link

mutech commented Jan 21, 2021

Oh I meant that your ticket is more interesting, if closing was a reaction on my comment ;-)

@RamoFX
Copy link
Author

RamoFX commented Jan 21, 2021

Sorry, I have little problem with understanding english. Maybe two duplicated issues make contributors think about this after several years.

@RamoFX RamoFX reopened this Jan 21, 2021
@Zemnmez
Copy link

Zemnmez commented Aug 20, 2021

I agree that I rarely need this feature, however when I use any of the 'tsconfig' packages, e.g. https://www.npmjs.com/package/@tsconfig/node12, I often want to use both that and some base config that has my common rules in. Currently, the only way to use tsconfig packages is to maintain parity -- which is, to some extent just fine.

@johncmunson
Copy link

johncmunson commented Jan 22, 2022

I would just like to post a concrete example I've come across where multiple inheritance could potentially be helpful.

I've been setting up a Typescript monorepo structure that looks something like this. Of course, there are other workspaces besides just foo, but this structure is enough to demonstrate the issue at hand.

my-project
|_ tsconfig.build.json
|_ tsconfig.json
|_ foo
  |_ tsconfig.build.json
  |_ tsconfig.json
  |_ src
    |_ index.ts

Now, you may be wondering why there are two different versions of tsconfig, both at the root level and the workspace level. This is because I've been following the technique described in this article for allowing better integration with tooling such as VSCode.

The technique relies on utilizing path aliases while in development, but excluding them when running the build. For example, this is my current root level tsconfig.json...

{
  // The purpose of this file is to enable better integration
  // between our Typescript monorepo and IDEs and other tooling
  // that expects to find a file named tsconfig.json. The important
  // thing is the "paths" property below which sets path aliases.
  // So when the IDE sees an import starting with @marketing-milk/foo,
  // instead of resolving to the build output inside of node_modules,
  // it will instead resolve to the actual src of foo. This has a number
  // of advantages...
  //   - You can iterate on foo and dependent workspaces will
  //     immediately see the changes. No need to rebuild foo.
  //   - You can clone the project and everything will just
  //     work out of the box without needing to run the builds.
  //   - Go To Definiton will work as expected and take you to
  //     the correct location.
  "extends": "./tsconfig.build.json",
  "compilerOptions": {
    "paths": {
      "@marketing-milk/*": ["*/src"]
    },
    // Any tooling that reads from this file in realtime, such
    // as VSCode, should not be producing any output.
    "noEmit": true
  }
}

However, once you get to the workspace level and you setup the same tsconfig.json / tsconfig.build.json dichotomy, there is an ambiguity that is introduced. There has already been a precedent set that tsconfig.json should extend from the sibling tsconfig.build.json. But the tsconfig.json at the workspace level of course needs to somehow inherit the path aliases from the root level tsconfig.json.

For a tsconfig.json at the workspace level, it seems there are two conflicting needs, and you can only choose one.

  • the need to inherit workspace level settings and overrides from ./foo/tsconfig.build.json
  • the need to inherit global path aliases from ./tsconfig.json

So, naively one might think that being able to do something like this is a great idea...

{ "extends": ["../tsconfig.json", "./tsconfig.build.json"] }

But then you have to decide which order the array items should be, to indicate which should take precedence in the event of a conflict, and there's not necessarily a correct answer there. It would also probably mean that the compiler would need a mechanism for resolving the diamond problem whenever it is encountered.

My personal opinion is that it would be awesome to have this feature, and people can use at their own risk.

Edit: Just realized that this flag already exists! --showConfig If this feature were introduced, it would be super beneficial to have some sort of CLI flag that allows you to print out the final resolved configuration. Because when one tsconfig extends another, it's not always clear what Typescript is deciding the final output should be, and this would be especially true if multiple inheritance was introduced. Basically, it would just be great for debugging.

@ts-web
Copy link

ts-web commented May 17, 2023

This feature is mentioned in the 5.0 release blog post though it's still not mentioned in the tsconfig extends documentation

@MarArMar
Copy link

So is this available in typescript 5 ?

@AdrianFahrbach
Copy link

So is this available in typescript 5 ?

Yes. It seems to be working for me.

@mrgrain
Copy link

mrgrain commented May 10, 2024

This is implemented, but not yet documented here: https://www.typescriptlang.org/tsconfig/#extends

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests