microsoft / dtslint

A utility built on TSLint for linting TypeScript declaration (.d.ts) files.
MIT License
925 stars 86 forks source link

`extends` in `tsconfig.json` not recognised #254

Open OliverJAsh opened 5 years ago

OliverJAsh commented 5 years ago

I have the following tsconfig.json in my tests folder:

{
  "extends": "../tsconfig-base.json",
  "include": [
    "../shared/typings/*",
    "**/*"
  ]
}

When I try to use dtslint, it errors with:

TypeError: Cannot use 'in' operator to search for 'lib' in undefined
    at Object.<anonymous> (/Users/oliverash/Development/unsplash-web/node_modules/dtslint/bin/checks.js:103:21)
    at Generator.next (<anonymous>)
    at fulfilled (/Users/oliverash/Development/unsplash-web/node_modules/dtslint/bin/checks.js:4:58)

If I define an empty compilerOptions, it then errors with:

Error: Must specify "lib", usually to `"lib": ["es6"]` or `"lib": ["es6", "dom"]`.
    at Object.<anonymous> (/Users/oliverash/Development/unsplash-web/node_modules/dtslint/bin/checks.js:103:19)
    at Generator.next (<anonymous>)
    at fulfilled (/Users/oliverash/Development/unsplash-web/node_modules/dtslint/bin/checks.js:4:58)

Even though there is a lib option specified inside the extend config (../tsconfig-base.json).

OliverJAsh commented 4 years ago

Hey @sandersn, sorry to pester but do you consider this a bug or working as intended?

sandersn commented 4 years ago

bug + help wanted: definitely typed doesn't need this but there's no reason it shouldn't work

OliverJAsh commented 4 years ago

Here's a patch to work around this. I don't have time to turn this into a PR right now, but maybe someone else does.

patch-package
new file mode 100644
--- /dev/null
+++ b/node_modules/dtslint/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+    "eslint.enable": false
+}
\ No newline at end of file
--- a/node_modules/dtslint/bin/util.js
+++ b/node_modules/dtslint/bin/util.js
@@ -64,13 +64,37 @@ function getModuleDeclarationStatements(node) {
     return body && ts.isModuleBlock(body) ? body.statements : undefined;
 }
 exports.getModuleDeclarationStatements = getModuleDeclarationStatements;
+// See https://github.com/microsoft/dtslint/issues/254
+function getConfig(tsconfigPath) {
+  return __awaiter(this, void 0, void 0, function* () {
+      if (!(yield fs_extra_1.pathExists(tsconfigPath))) {
+          throw new Error(`Need a 'tsconfig.json' file`);
+      }
+      const config = yield readJson(tsconfigPath);
+
+      const currentDir = path_1.dirname(tsconfigPath);
+
+      const base = config.extends !== undefined ? yield getConfig(path_1.join(currentDir, config.extends)) : {};
+
+      return {
+        ...base,
+        ...config,
+        compilerOptions: {
+          ...base.compilerOptions,
+          ...config.compilerOptions
+        }
+      };
+  })
+};
 function getCompilerOptions(dirPath) {
     return __awaiter(this, void 0, void 0, function* () {
         const tsconfigPath = path_1.join(dirPath, "tsconfig.json");
         if (!(yield fs_extra_1.pathExists(tsconfigPath))) {
             throw new Error(`Need a 'tsconfig.json' file in ${dirPath}`);
         }
-        return (yield readJson(tsconfigPath)).compilerOptions;
+        const config = (yield getConfig(tsconfigPath));
+
+        return config.compilerOptions;
     });
 }
 exports.getCompilerOptions = getCompilerOptions;
StreetStrider commented 3 years ago

@OliverJAsh looks like a hack. I think, TypeScript language api should be used for this kind of tasks by itself. Something like ts.createProgram (I'm not sure). There must be specific method for that task.