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

Add template variable ${configDir} (name to be determined) for file path substitution #57485

Closed
6 tasks done
sheetalkamat opened this issue Feb 22, 2024 · 9 comments Β· Fixed by #58042
Closed
6 tasks done
Assignees

Comments

@sheetalkamat
Copy link
Member

sheetalkamat commented Feb 22, 2024

πŸ” Search Terms

"extends", "compilerOptions", "paths", "outdir", "include", "exclude", "typeRoots", "tsconfig", "ability to make tsconfig paths relative to final config"

βœ… Viability Checklist

⭐ Suggestion

Subset of #56436

Today when all the options that are file paths, are always relative to config they are specified in. But that also means that if you are extending tsconfig and you want eg say outDir to be same name but relative to your config, you have to re-specify it in the config. The proposal is to use template variable in base config which would mean that the resulting file paths are relative to final config directory. Name is to be determined.

Consider:

// @fileName: /temp/test/base.tsconfig.json
{
    "compilerOptions": {
        "typeRoots": ["node_modules/@types"],
        "outDir": "dist"
    }
}
// @fileName: /temp/test/project1/tsconfig.json
{
    "extends": "../base.tsconfig.json"
}

Today the resulting config of project1 is:

// @fileName: /temp/test/project1/computed.tsconfig.json
{
    "compilerOptions": {
        "typeRoots": ["../node_modules/@types"],
        "outDir": "../dist"
    }
}

Proposal is to write base.tsconfig.json as:

// @fileName: /temp/test/base.tsconfig.json
{
    "compilerOptions": {
        "typeRoots": ["${configDir}/node_modules/@types"],
        "outDir": "${configDir}/dist"
    }
}

and this should result in computed tsconfig.json as:

// @fileName: /temp/test/project1/computed.tsconfig.json
{
    "compilerOptions": {
        "typeRoots": ["./node_modules/@types"],
        "outDir": "./dist"
    }
}

Names that came up in design meeting:

  • configLocation
  • configFolder
  • configDirectory
  • projectLocation
  • projectFolder
  • projectDirectory

πŸ“ƒ Motivating Example

A way to specify root config that can specify include and/or outDir and not needing to write than in each project.
Issues: #29172, #30163, #37227, #45050, #51213

πŸ’» Use Cases

  1. What do you want to use this for?
  2. What shortcomings exist with current approaches?
  3. What workarounds are you using in the meantime?
@sheetalkamat
Copy link
Member Author

sheetalkamat commented Mar 29, 2024

Options that should check for ${configDir}
Some of these options can be passed on commandline. Do we allow passing ${configDir} in them

Option Category Option Type isFilePath
CompilerOptions outDir string true
CompilerOptions declarationDir string true
CompilerOptions outFile string true
CompilerOptions rootDir string true
CompilerOptions baseUrl string true
CompilerOptions tsBuildInfoFile string true
CompilerOptions rootDirs string[] true
CompilerOptions typeRoots string[] true
CompilerOptions paths object false values need to be lookedup and substituted
WatchOptions excludeFiles string[] true
WatchOptions excludeDirectories string[] true
Root files string[] false
Root include string[] false
Root exclude string[] false

Options that are of type string or object but should not check ${configDir}

Option Category Option Type isFilePath
CompilerOptions types string[] false
CompilerOptions moduleSuffixes string[] false
CompilerOptions customConditions string[] false
CompilerOptions sourceRoot string false we use value as is
CompilerOptions mapRoot string false we use value as is
CompilerOptions jsxFactory string false
CompilerOptions jsxFragmentFactory string false
CompilerOptions jsxImportSource string false
CompilerOptions out string false deprecated and suppose to be used as is
CompilerOptions ignoreDeprecations string false
CompilerOptions reactNamespace string false
CompilerOptions charset string false
CompilerOptions plugins object false should not map names as we dont allow relative module names
CompilerOptions project string true Commandline only
CompilerOptions generateCpuProfile string true Commandline only, if commandline ${configDir} is allowed is this ok to pass?
CompilerOptions generateTrace string true Commandline only, if commandline ${configDir} is allowed is this ok to pass?
CompilerOptions locale string false Commandline only
TypeAcquisition include string[] false
TypeAcquisition exclude string[] false
Root extends string or string[] false this is directly in the config so no point of having ${configDir}
Root references object false references are not inherited, so no need of substitution

@Bessonov
Copy link

Thank you, @sheetalkamat, you are amazing!

@karlhorky
Copy link
Contributor

karlhorky commented Apr 19, 2024

@sheetalkamat Awesome job, thanks! πŸŽ‰ looking forward to having this released in a TypeScript version for my shared tsconfigs 😍

Is it planned that this will be released in TypeScript 5.5? I didn't see it in the Iteration Plan:

@D4N14L
Copy link
Member

D4N14L commented Apr 19, 2024

@sheetalkamat thank you! This has been a feature I've wanted to see for some time now. Great to finally have it!

@karlhorky
Copy link
Contributor

karlhorky commented Apr 29, 2024

Is it planned that this will be released in TypeScript 5.5? I didn't see it in the Iteration Plan

Looks like will be a part of TS 5.5 (or at least is in the 5.5 Beta announcement):

@simonhaenisch
Copy link

simonhaenisch commented May 8, 2024

Nice, I've just tried this out yesterday and it works like a charm.

Only issue I had was that somehow Intellisense in VS Code still showed me an error in the editor which wasn't actually a build error, like it doesn't understand the ${configDir} variable yet.

// base.json
{
  // ...
  "include": ["some-file.d.ts", "${configDir}/src"]
}
// some/path/tsconfig.json
{
  "extends": "../../base.json"
}

☝️ this gave me the error so i tried moving the include into the composite project's tsconfig.json and that worked:

// some/path/tsconfig.json
{
  "extends": "../../base.json",
  "include": ["../../some-file.d.ts", "src"]
}

but then I tried using ${configDir} there as well and that didn't work either (thus the assumption that the var breaks it):

// some/path/tsconfig.json
{
  "extends": "../../base.json",
  "include": ["${configDir}/../../some-file.d.ts", "src"]
}

As I already said, it's only an error shown in the IDE (I did switch the workspace to use the project's typescript instead of the built-in one), running tsc works fine.

Maybe I'll just have to wait for VS Code to update the built-in TypeScript version once 5.5 is officially published (:

@ChurroC
Copy link

ChurroC commented May 11, 2024

Nice, I've just tried this out yesterday and it works like a charm.

Only issue I had was that somehow Intellisense in VS Code still showed me an error in the editor which wasn't actually a build error, like it doesn't understand the ${configDir} variable yet.

// base.json
{
  // ...
  "include": ["some-file.d.ts", "${configDir}/src"]
}
// some/path/tsconfig.json
{
  "extends": "../../base.json"
}

☝️ this gave me the error so i tried moving the include into the composite project's tsconfig.json and that worked:

// some/path/tsconfig.json
{
  "extends": "../../base.json",
  "include": ["../../some-file.d.ts", "src"]
}

but then I tried using ${configDir} there as well and that didn't work either (thus the assumption that the var breaks it):

// some/path/tsconfig.json
{
  "extends": "../../base.json",
  "include": ["${configDir}/../../some-file.d.ts", "src"]
}

As I already said, it's only an error shown in the IDE (I did switch the workspace to use the project's typescript instead of the built-in one), running tsc works fine.

Maybe I'll just have to wait for VS Code to update the built-in TypeScript version once 5.5 is officially published (:

You can go to a ts file then on the bottom right you can see a typescript button. If you press it you can select vs code ts version and set it to the projects version. If you downloaded the 5.5.0-beta from npm vs code could be set to use that type.

@simonhaenisch
Copy link

simonhaenisch commented May 13, 2024

@ChurroC

I did switch the workspace to use the project's typescript instead of the built-in one

maybe you overlooked this?

Edit: anyway you're right. Even though I had done this before via command palette which created

{
  "typescript.tsdk": "node_modules/typescript/lib"
}

in the project's .vscode/settings.json (which I also committed), somehow it wasn't working anymore after restarting VS Code. I just manually switched the version again and now it's working as expected. πŸ€·πŸ»β€β™‚οΈ

@jakearchibald
Copy link

This feature should be documented somewhere outside of https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-5.html#the-configdir-template-variable-for-configuration-files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
7 participants