ts-ignore
What // @ts-ignore does
@ts-ignoreis a TypeScript compiler directive that makes the compiler skip the next line of code, even if it contains type errors.
Example:
// @ts-ignore
const x: number = "hello"; // Error, but TS stays silentThe compiler does not check this line at all. Typing is disabled 100%, but only right here, and the consequences can spread further.
Why @ts-ignore is dangerous
1. It defeats the purpose of TypeScript
TypeScript was created to catch errors before the code runs.
@ts-ignore literally tells the compiler:
"Don't check, I know what I'm doing."
Example:
// @ts-ignore
user.profile.name.toUpperCase();If user turns out to be null, the code crashes at runtime,
and the compiler will not even warn you.
2. It easily becomes a "habitual crutch"
Developers often add @ts-ignore
when they do not want to deal with types right now:
// @ts-ignore - "I'll figure it out later"
someFunction(possiblyUndefinedValue);A few months later, nobody remembers why the ignore was there. The surrounding types may have changed, and TS no longer protects against new errors.
3. It hides real design problems
Sometimes @ts-ignore masks an architectural mistake.
Example:
function getUser() {
// returns null or undefined
}
// @ts-ignore
getUser().name; // TS thinks everything is fineInstead of fixing the function's type (User | null),
the developer simply "silenced" TS.
This is technical debt that later blows up in production.
4. It gets in the way of refactoring
TypeScript helps you safely rename fields and move functions.
But if @ts-ignore sits next to that code, TS loses context and cannot tell you
that the code needs updating.
Example:
// @ts-ignore
userData.adress = "NY"; // a typo! but TS stays silentIn the types, adress has already been renamed to address,
but @ts-ignore hid all of it.
5. It can "infect" the type system
Types in TS often "leak" further through the code. If you disable typing in one spot, errors can "seep" into other parts of the application.
Example:
// @ts-ignore
const response = fetchSomething(); // now any
response.data.id; // TS does not check thisany propagates further, and the IDE stops offering suggestions.
6. @ts-ignore is not the same as @ts-expect-error
Many people confuse these two directives.
| Directive | What it does | When it is useful |
|---|---|---|
@ts-ignore | Completely disables the check | Better to avoid |
@ts-expect-error | Ignores the error, but warns you if the error disappears | A safer option |
Example:
// @ts-expect-error: known issue with library typing
someLegacyFunction("abc");If the types are fixed later, TS reports that expect-error is no longer needed.
@ts-ignore just stays silent forever.
How "ts-ignore" ruins a project in practice
Imagine code with 20-30 @ts-ignore comments:
- The IDE no longer knows what is typed where.
- Checks become selective.
- Refactoring turns into "walking through a minefield".
- Any change can trigger a crash that TS will not notice.
In effect, the project loses one of TypeScript's key benefits: type integrity.
When using @ts-ignore is still justified
Sometimes there really is no other way.
Here are cases where @ts-ignore is acceptable:
1. Temporary problems with external types (for example, from npm)
Sometimes a library has broken or incompatible types, and a fix is a long way off.
Example:
// @ts-ignore: typings are wrong in library v2.1.0
import brokenLib from "broken-lib";Justified, if you record the reason and version in a comment.
2. When migrating from JS to TS (in legacy code)
If you have a huge legacy codebase that you are migrating gradually, sometimes you need to temporarily skip a couple of errors.
Example:
// @ts-ignore: legacy code, will fix later
initializeLegacyModule(config);The key is to mark it with a TODO and track the debt (for example, with a linter).
3. When working with dynamic APIs (for example, window, global)
When an object is created dynamically and TS simply does not know about it.
Example:
// @ts-ignore: injected by analytics script
window.analytics.trackEvent("click");It is better to add typing (declare global),
but if it is a one-off call, this is acceptable.
4. When testing edge cases (internal hacks)
Sometimes you need to intentionally "break" the types to check how the system reacts.
Example:
// @ts-ignore: intentional invalid input for test
validateUser(123 as any);This is sometimes justified in tests.
5. In code generators or low-level utilities
For example, when integrating with the DOM API, when TS simply cannot infer a correct type.
Example:
// @ts-ignore: forced casting for internal optimization
element.style["--custom-color"] = "red";How to do it correctly instead of @ts-ignore
| Problem | Correct solution |
|---|---|
| Type error in a library | Add a @types/... package or a declare module |
| Unknown type | Use unknown or any with a comment |
| Possibly undefined property | Add optional chaining (?.) |
| Implicit coercion | Use as const or a more precise type |
| Transitional code | Wrap it in a function with a clearly typed interface |
Example:
// Bad
// @ts-ignore
user.age.toFixed();
// Good
if (user?.age != null) {
user.age.toFixed();
}How to control the abuse of @ts-ignore
Add a rule to ESLint:
"@typescript-eslint/ban-ts-comment": ["error", {
"ts-ignore": true,
"ts-expect-error": "allow-with-description"
}]Now @ts-ignore will be forbidden,
and @ts-expect-error will be allowed only with an explanation.
Summary
| Question | Answer |
|---|---|
| Why is it dangerous? | It fully disables type checking, hides errors, and breaks type safety |
| When is it acceptable? | Temporary crutches: broken library types, legacy code, tests, global objects |
| What's better? | Using @ts-expect-error with a description of the reason |
| Alternative | Fix the typing, refine the type, use unknown or declare |
| Best practice | 0 @ts-ignore in production, at most in tests and migrations |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.