microsoft / TypeScript

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

Compiler API allow custom options in parseCommandLine/ConfigFile #26187

Open lolleko opened 6 years ago

lolleko commented 6 years ago

Search Terms

parser options compiler api

Suggestion

Add a way to pass additional custom options to the CLI Parser.

Use Cases

We currently work on a tool transpiling Typescript to Lua. This works by doing the type checking via the compiler API. And then transpiling the AST to Lua instead of JS.

We want the user to pass typecheck options via CLI or a tsconfig file. Currently we do that by using parseCommandLine and readConfigFile/parseJsonConfigFileContent which are both exposed by the compiler API. That way the user can use the Lua compiler in the same way he uses tsc.

The issue is that its hard to add custom options into the parse process because parseCommandLine reports an error if an option is invalid. Currently we just ignore errors if they were cause by our custom options but its not a really clean workaround. Same issue for parseJsonConfigFileContent for a workaround there we currently add the options outside compilerOptions{} e.g:

{
  "luaTarget": "5.1",
  "compilerOptions": {...}
}

This also is not real ideal for us.

We don't really want to write our own parser for all tsc options or use some 3rdparty CLI parser in addition to using parseCommandLine. We also don't really want to use our own typescript fork.

Implementation

It would be ideal if we could just pass our own optionDeclarations based on const optionDeclarations: CommandLineOption[] or OptionNameMap to parseCommandLine and parseJsonConfigFileContent.

One possible way to to this is add a optional parameter to these function that contains an OptionMap and instead of getting the options via getOptionMap / getOptionFromMap that passed parameter would be used.

This would require to merge the additional options with the default options before passing them to the function. An alternative could be that the parameter only gets the additional options and merging is done inside the parser function, that way optionDeclarations would not need to be exposed.

In addition soem option related const/functions/enums might need to be expose.

TL;DR this could be implemented without changing any functionality and only refactoring commandLineParser.ts a bit (EDIT: actually I think it would require a lot of refactoring). I can also provide you with a PR.

Examples

What we currently do: https://github.com/Perryvw/TypescriptToLua/blob/master/src/CommandLineParser.ts

We could basically replace most of that with:

let typescriptToLuaOptions: OptionNameMap = {
  // our custom options
}
let commandLine = ts.parseCommandLine(args, typescriptToLuaOptions);

Checklist

My suggestion meets these guidelines:

RyanCavanaugh commented 6 years ago

It'd be great to understand what's suboptimal about having the options outside compilerOptions - a fair number of tools do this today and haven't complained, but we're open to feedback here

lolleko commented 6 years ago

You still have to validate them with some custom logic, since they are just stored in ParsedCommandLine.raw as parsed JSON irrc. This isn't to big of an issue.

The main issue is that we have to merge the additional options from raw back into CompilerOptions because we need values from both for our transpilation process.

fightingcat commented 5 years ago

One year passed...