How to set up vue-tsc to properly work with lint-staged (staged files)?

959 Views Asked by At

With a recent introduction of TypeScript to a project, our team decided not to do a full-blown type check inside a CI pipeline, but rather fix the problems gradually. One plan was to run a compiler on staged files only and check for any errors present. I tried multiple approaches inside .lintstagedrc.js, for example:

  1. Running a vue-tsc command with a --project flag pointing to a custom tsconfig which contains include property which is an array of absolute paths to all the staged files
  2. Running a vue-tsc command with flags specified in a way that mimics the tsconfig that's being used in the app

The problem with the first approach is (I believe) that if any other component/file is imported inside the component - TS will throw an error that the import or its type declaration can't be resolved because only staged files are inside include of the tsconfig.

The problem with the second approach (so far) is that there's no way I can provide path mappings (which are actively used throughout the app). I'm sure there would be some additional errors.

Here's the code snippet of a .lintstagedrc.js:

const fileSystem = require("fs");

function typeCheckStagedFiles(files) {
  const configName = "tsconfig.lintstaged.json";
  const config = JSON.parse(
    fileSystem.readFileSync("./tsconfig.app.json", "utf8")
  );
  config.compilerOptions.noEmit = true;
  config.compilerOptions.composite = false;
  config.include = files.map((file) => file.split("dashboard/")[1]);

  fileSystem.writeFileSync(`./${configName}`, JSON.stringify(config));

  return `vue-tsc -p ${configName}`;
}

module.exports = {
  "src/**/*.{ts,cts,mts,js,cjs,mjs,vue}": [
    "prettier --write",
    "eslint --fix --max-warnings 0"
  ],
  "src/**/*.{vue}": [typeCheckStagedFiles]
};

Here's the tsconfig that's being overridden:

{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "compilerOptions": {
    "composite": true,
    "strict": true,
    "importHelpers": true,
    "moduleResolution": "node",
    "allowJs": true,
    "outDir": "dist",
    "checkJs": false,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "resolveJsonModule": true,
    "types": ["vite/client"],
    "paths": {
      "@/*": ["src/*"],
      "@tests/*": ["tests/*"]
    },
    "lib": ["ES2021", "DOM", "DOM.Iterable"]
  },
  "include": [
    "src/**/*.js",
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "env-override.d.ts"
  ],
  "exclude": ["node_modules", "dist"]
}

Thanks in advance for any help provided.

0

There are 0 best solutions below