Skip to content

Using strictNullChecks causes VSCode type check slowdown #60666

Closed as not planned
@os-tohe

Description

@os-tohe

🔎 Search Terms

"strictNullChecks slow", "ts-plugin slow"

🕗 Version & Regression Information

This changed when we updated all typescript and eslint related packages. We replaced @vue/eslint-config-typescript v12.0.0 with typescript-eslint v8.17.0, since the first package caused problems in mono repos.

⏯ Playground Link

No response

💻 Code

// Changing this:
const hello = () => {
  return true;
};

hello();

// To this:
const hello = (value: string) => {
  return true;
};

hello();

🙁 Actual behavior

Takes over 5 seconds to show an error about the missing parameter. This happens only in .vue files and in .test.ts files which use Vue components. If I remove all imported components from the component template the type check time becomes almost instant. Regular .ts files show the error instantly.

🙂 Expected behavior

It should show the error almost instantly.

Additional information about the issue

This all started when we updated our eslint and typescript packages and eslint configuration. Our configuration is based on this comment: vuejs/eslint-config-typescript#76 (comment)

If I set the "strictNullChecks" to false in tsconfig, everything works instantly. I am running out of ideas how I can fix this, maybe someone who knows these things inside out can instantly point out what is wrong with our tsconfig or eslint configuration?

tsconfig.json:

{
  // This tsconfig extends these files:
  // https://github.com/vuejs/tsconfig/blob/main/tsconfig.json (this is extended by below dom.json)
  // https://github.com/vuejs/tsconfig/blob/main/tsconfig.dom.json
  // https://github.com/vuejs/tsconfig/blob/main/tsconfig.lib.json
  "extends": ["@vue/tsconfig/tsconfig.dom.json", "@vue/tsconfig/tsconfig.lib.json"],
  "compilerOptions": {
    "paths": {
      "@/*": ["./src/*"]
    },

    // Fix building Vue components
    "moduleResolution": "node",
    "outDir": "dist",

    // Fix importing translations
    "allowSyntheticDefaultImports": true,

    "types": [
      "vitest/globals",
      "@vitest/browser/providers/playwright",
      "vitest-browser-vue"
    ]
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "references": [{ "path": "./tsconfig.node.json" }],
  "exclude": ["src/App.vue", "src/main.ts"]
}

tsconfig.node.json:

{
  "compilerOptions": {
    "composite": true,
    "skipLibCheck": true,
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowSyntheticDefaultImports": true
  },
  "include": ["vite.config.ts"]
}

eslint.config.js:

import globals from 'globals';
import js from '@eslint/js';
import ts from 'typescript-eslint';
import vue from 'eslint-plugin-vue';
import prettier from 'eslint-plugin-prettier/recommended';
import comments from '@eslint-community/eslint-plugin-eslint-comments/configs';

export default [
  {
    ignores: ['**/node_modules/*', '**/dist/*'],
  },

  // globals
  {
    languageOptions: {
      globals: {
        ...globals.browser,
        ...globals.node,
      },
    },
  },

  // js
  js.configs.recommended,
  {
    rules: {
      'no-unused-vars': 'off',
      'no-undef': 'off',
    },
  },

  // comments
  comments.recommended,

  // ts
  ...ts.configs.recommended,
  {
    rules: {
      '@typescript-eslint/no-unused-vars': 'warn',
      '@typescript-eslint/no-explicit-any': 'error',
    },
  },

  // vue
  ...vue.configs['flat/recommended'],
  {
    files: ['*.vue', '**/*.vue'],
    languageOptions: {
      parserOptions: {
        parser: ts.parser,
      },
    },
  },

  {
    languageOptions: {
      parserOptions: {
        ecmaVersion: 'latest',
      },
    },
    files: [
      '**/*.vue',
      '**/*.js',
      '**/*.jsx',
      '**/*.cjs',
      '**/*.mjs',
      '**/*.ts',
      '**/*.tsx',
      '**/*.cts',
      '**/*.mts',
    ],
    rules: {
      'prefer-const': 'error',
      '@typescript-eslint/ban-ts-comment': [
        'error',
        {
          'ts-expect-error': 'allow-with-description',
          'ts-ignore': 'allow-with-description',
          'ts-nocheck': 'allow-with-description',
          'ts-check': 'allow-with-description',
          minimumDescriptionLength: 10,
        },
      ],
      '@eslint-community/eslint-comments/require-description': [
        'error',
        { ignore: ['eslint-env', 'eslint-enable'] },
      ],
    },
  },

  // prettier
  prettier,
  {
    rules: {
      'prettier/prettier': 'error',
    },
  },
];

Installed versions:

"@eslint-community/eslint-plugin-eslint-comments": "^4.4.1",
"@eslint/js": "^9.16.0",
"@vue/tsconfig": "^0.7.0",
"eslint": "^9.16.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-vue": "^9.32.0",
"globals": "^15.13.0",
"prettier": "^3.4.1",
"typescript": "^5.7.2",
"typescript-eslint": "^8.17.0",
"vue": "^3.5.13"

Metadata

Metadata

Assignees

No one assigned

    Labels

    ExternalRelates to another program, environment, or user action which we cannot control.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions