microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
98.08k stars 12.19k forks source link

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

Closed sheetalkamat closed 2 weeks ago

sheetalkamat commented 2 months ago

🔍 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:

📃 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 commented 1 month ago
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 commented 2 weeks ago

Thank you, @sheetalkamat, you are amazing!

karlhorky commented 1 week ago

@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 commented 1 week ago

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

karlhorky commented 3 days ago

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):