Suggest an editImprove this articleRefine the answer for “ts-ignore”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`@ts-ignore`** is a TypeScript compiler directive that **makes the compiler skip the next line of code**, even if it contains type errors. **Key point:** typing is disabled 100% only on that line, but the consequences can spread further, so `@ts-ignore` should be avoided in favor of safer alternatives.Shown above the full answer for quick recall.Answer (EN)Image## What `// @ts-ignore` does > `@ts-ignore` is a **TypeScript compiler directive** > that **makes the compiler skip the next line of code**, > even if it contains **type errors**. Example: ```javascript // @ts-ignore const x: number = "hello"; // Error, but TS stays silent ``` The 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: ```javascript // @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: ```javascript // @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: ```javascript function getUser() { // returns null or undefined } // @ts-ignore getUser().name; // TS thinks everything is fine ``` Instead 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: ```javascript // @ts-ignore userData.adress = "NY"; // a typo! but TS stays silent ``` In 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: ```javascript // @ts-ignore const response = fetchSomething(); // now any response.data.id; // TS does not check this ``` `any` 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: ```javascript // @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: ```javascript // @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: ```javascript // @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: ```javascript // @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: ```javascript // @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: ```javascript // @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: ```javascript // 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: ```javascript "@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 |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.