---
id: typescript
sidebar_label: TypeScript
title: TypeScript FAQs
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

## Should TypeScript be installed globally or locally?

Make sure that you have installed TypeScript locally i.e. by using `npm install typescript`, not `npm install -g typescript`,
or by using `pnpm add typescript`, not `pnpm add -g add typescript`.
See [#2041](https://github.com/typescript-eslint/typescript-eslint/issues/2041) for more information.

## Why don't I see TypeScript errors in my ESLint output?

TypeScript's compiler (or whatever your build chain may be) is specifically designed and built to validate the correctness of your codebase.
Our tooling does not reproduce the errors that TypeScript provides, because doing so would slow down the lint run [1], and duplicate the errors that TypeScript already outputs for you.

Instead, our tooling exists to **_augment_** TypeScript's built in checks with lint rules that consume the type information in new ways beyond just verifying the runtime correctness of your code.

[1] - TypeScript computes type information lazily, so us asking for the errors it would produce from the compiler would take an _additional_ ~100ms per file.
This doesn't sound like a lot, but depending on the size of your codebase, it can easily add up to between several seconds to several minutes to a lint run.

## How can I specify a TypeScript version / `parserOptions.typescriptLocation`?

You can't, and you don't want to.

You should use the same version of TypeScript for linting as the rest of your project.
TypeScript versions often have slight differences in edge cases that can cause contradictory information between typescript-eslint rules and editor information.
For example:

- `@typescript-eslint/strict-boolean-expressions` might be operating with TypeScript version _X_ and think a variable is `string[] | undefined`
- TypeScript itself might be on version _X+1-beta_ and think the variable is `string[]`

See [this issue comment](https://github.com/typescript-eslint/typescript-eslint/issues/4102#issuecomment-963265514) for more details.

## Why aren't `// @ts-expect-error` or `// @ts-ignore` comments affecting lint results?

[`// @ts-expect-error`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-9.html#-ts-expect-error-comments) and [`// @ts-ignore`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-6.html#suppress-errors-in-ts-files-using--ts-ignore-comments) comment directives are a feature of TypeScript.
They only impact TypeScript's type checking.
TypeScript (a type checker) is a separate tool from ESLint (a linter).

Similar, [ESLint configuration comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments) like `/* eslint ... */` only impact ESLint.
They don't change anything with TypeScript's type checking.

:::tip
You can use ESLint to enforce good uses of both ESLint and TypeScript comment directives:

- The [`@typescript-eslint/ban-ts-comment`](/rules/ban-ts-comment) rule can disallow `@ts-...` comments and/or require comment descriptions to explain their use
- The [`@eslint-community/eslint-plugin-eslint-comments`](https://eslint-community.github.io/eslint-plugin-eslint-comments) plugin can enforce general ESLint comment best practices, including requiring descriptions

:::

## How should I handle reports that conflict with [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax)?

Several TypeScript options impact how imports and exports are handled in your project, including:

- [`allowSyntheticDefaultImports`](https://www.typescriptlang.org/tsconfig/#allowSyntheticDefaultImports)
- [`esModuleInterop`](https://www.typescriptlang.org/tsconfig/#esModuleInterop)
- [`importsNotUsedAsValues`](https://www.typescriptlang.org/tsconfig/#importsNotUsedAsValues)
- [`preserveValueImports`](https://www.typescriptlang.org/tsconfig/#preserveValueImports)
- [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax)

Additionally, whether one is authoring ES Modules or CommonJS impacts `import`/`export`/`require` semantics.
Some of our rules may not apply or may need special configuration in projects using these options.

For example, the default behavior of [no-require-imports](/rules/no-require-imports) prohibits CommonJS `require` syntax entirely, but `verbatimModuleSyntax` requires it when authoring CommonJS modules.
Therefore, you'll need to configure the rule to permit `import x = require('foo')` syntax.

Known rules that conflict with or require special configuration to be used with `verbatimModuleSyntax` include:

- [consistent-type-imports](/rules/consistent-type-imports#comparison-with-importsnotusedasvalues--verbatimmodulesyntax): should be disabled
- [no-import-type-side-effects](/rules/no-import-type-side-effects): a rule that is only needed at all when using `verbatimModuleSyntax`
- [no-namespace](/rules/no-namespace#when-not-to-use-it): some reports [need to be ignored](/rules/no-namespace#when-not-to-use-it)
- [no-require-imports](/rules/no-require-imports): requires [configuring its `allowAsImport` option](/rules/no-require-imports#allowasimport)

If you are using the [`importsNotUsedAsValues`](https://www.typescriptlang.org/tsconfig/#importsNotUsedAsValues), [`isolatedModules`](https://www.typescriptlang.org/tsconfig/#isolatedModules), and/or [`preserveValueImports`](https://www.typescriptlang.org/tsconfig/#preserveValueImports) TSConfig options, you may need to additionally configure those lint rules as well.
See the rules' documentation for more information.
