Typescript: In tsc cli can't override declaration to false when tsconfig.json contains declarationDir option?

Created on 28 Jan 2018  路  12Comments  路  Source: microsoft/TypeScript



TypeScript Version: 2.6.2 xxxxx


Search Terms:

"Option 'declarationDir' cannot be specified without specifying option 'declaration'"

Code

Assuming have tsconfig.json like this:

{
  "compilerOptions": {
    "module": "esnext",
    "target": "es6",
    "lib": ["es6", "dom"],
    "moduleResolution": "node",
    "declarationDir": "dist/types",
    "declaration": true,
  }
}

Expected behavior:
In terminal:

tsc --declaration false

or

tsc --declaration false ----declarationDir ''

wroks.

Actual behavior:

In terminal:

tsc --declaration false

reports: "error TS5052: Option 'declarationDir' cannot be specified without specifying option 'declaration'."

tsc --declaration false ----declarationDir ''

reports: "error TS6044: Compiler option 'declarationDir' expects an argument."

Playground Link:

Related Issues:

Declined

All 12 comments

TS6044 because empty string is falsey https://github.com/Microsoft/TypeScript/blob/master/src/harness/unittests/commandLineParsing.ts#L227
has a unit test similar for it

Looking at this again, I do not think we want to change this behavior really.. tsconfig.json allows for such overrides using extends and using null as an override value. i do not think the value we get from allowing this on the command line is wroth handling empty strings in all of our compiler options.

@mhegazy Consider this issue and its fix: https://github.com/ezolenko/rollup-plugin-typescript2/issues/52. Not only rollup-plugin-typescript, other plugins, e.g. ts-loader, which provides override feature and calls tsModule. parseJsonConfigFileContent from tsproxy inside, have this issue that once we specified the declarationDir in a base tsconfig.json we have no ways to cancel it.

rollup-plugin-typescript2 fixed it after this issue submitting by re-writing the parsed value of declarationDir to null if ppl try to override it by setting a null declarationDir, the procedure is consuming tsconfig.json and user's overrides and then call tsModule. parseJsonConfigFileContent to get parsed configs, modify the parsed declarationDir option if ppl setted declarationDir to null.

ts-loader also can't cancel declaration:

// webpack segment:

rules: [{
      test: /\.ts$/,
      loader: require.resolve('ts-loader'),
      options: {
        configFile: configFilePath,
        compilerOptions: {
          declaration: false,
        },
      },
    }],

image

Maybe there are many other plugins have the same issue, it is exhausted to fixing one by one. moreover, declaration cancelation is not documented by official site(seems only exists in this pr:https://github.com/Microsoft/TypeScript/pull/18058), normal users don't know the right way to cancel the declaration through tsconfig.json extending(json scheme defined it as string type, it is also a problem, need official document to back to update it), and plugin authors don't sure the right way to generated the final TS configs to feed to next procedure.

parseJsonConfigFileContent third argument is a set of overrides.. why is not sufficient for this scenario.. i.e.:

import * as ts from "typescript";

const optionsFromTsconfig = {
    compilerOptions: {
        declaration: true,
        declarationDir: "./declarationOut"
    }
};
const host = {
    fileExists: ts.sys.fileExists,
    readDirectory: ts.sys.readDirectory,
    readFile: ts.sys.readFile,
    useCaseSensitiveFileNames: false
}


const parsedOptions1 = ts.parseJsonConfigFileContent(optionsFromTsconfig, host, "./", { declaration: false });
const program1 = ts.createProgram(["./a.ts"], parsedOptions1.options, ts.createCompilerHost(parsedOptions1.options));
console.log(JSON.stringify(program1.getOptionsDiagnostics(), undefined, 2));  /// "Option 'declarationDir' cannot be specified without specifying option 'declaration'."

const parsedOptions2 = ts.parseJsonConfigFileContent(optionsFromTsconfig, host, "./", { declaration: false, declarationDir: null });
const program2 = ts.createProgram(["./a.ts"], parsedOptions2.options, ts.createCompilerHost(parsedOptions2.options));
console.log(JSON.stringify(program2.getOptionsDiagnostics(), undefined, 2));  /// no error

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

Hi @mhegazy

Looking at this again, I do not think we want to change this behavior really.. tsconfig.json allows for such overrides using extends and using null as an override value.

I'd like to ask to reconsider. First, it is not obvious that one can use null. Second, VS Code warns about null: Incorrect Type, expected "string".

The whole behavior is quite confusing. It would be really nice if simple and obvious declaration: false turned off the generation of declarations, without the need to investigate, search the web, find some issues on Github and comment on those! :)

First, it is not obvious that one can use null

That is a JSON feature really. we would be happy to take a PR to the docs to make that clear as well.

VS Code warns about null: Incorrect Type, expected "string".

This is coming from the schema in https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/tsconfig.json. Feel free to send a PR to update it, and tag me on it.

Thanks for quick response, much appreciated!

And now, also gulp-typescript doesn't work with "declarationDir": null, complains (see below). And changing docs and fixing schema is not a proper solution to the whole thing, in my opinion, we just cover up the actual problem: When user states (in tsconfig or via command line) that he/she doesn't want declarations via declaration: false, that should be enough, there is no need for tricky and unobvious extra actions, such as changing declarationDir for some reason. Please reconsider. At the moment: it is unobvious to user how to deal with this issue: 1. Confusing command-line 2. Unexpected and not recommended by VS Config tsconfig.json modification 3. Failing gulp-typescript.

This issue affects things all over the place :)

error TS5052: Option 'declarationDir' cannot be specified without specifying option 'declaration'.
error TS5052: Option 'declarationDir' cannot be specified without specifying option 'declaration'.
TypeScript: 1 options error
TypeScript: 1 emit error
TypeScript: emit failed
events.js:183
      throw er; // Unhandled 'error' event
      ^

so that rational works for --declaration but what about --outDir? what about --outFile? should these also have a flag that say --outDirEnabled?

I think these are very different cases. For declaration/declarationDir, they can't exist without each other. outDir and outFile can stand on their own.

To me, it is very natural that declarationDir should be required only when declaration is true. When declaration is false, it shouldn't matter what the value of declarationDir.

Here's my use case. We have a parent, core project, where we generate declarations for sub-projects to consume. In sub-projects we have tsproject.json files that extend the parent one, but set declaration to false. And we get the error for same reason. To me this is clearly a bug.

I am not sure why we are even debating this. I am probably missing some insight, but the current behavior is so weird and blatantly incorrect (to me, at least). I have to be missing something! :)

I am not sure why we are even debating this.

i am not sure either :) I believe we have a feature that accomplish the task in general fashion for all options. you are arguing that this should be done differently on a one-per-one basis.

I believe we have a feature that accomplish the task in general fashion for all options

With all respect, I'd disagree. You are not fully accomplishing the task, since users cannot adjust the configuration via command line properly. If the config file states that declarations must be created, and user doesn't want them, he/she CANNOT override this behavior via command line switch. This is a problem. One have to go to the config file and comment those settings out, which is not good for the command line use-case.... :)

Was this page helpful?
0 / 5 - 0 ratings