TypeScript: Ignore specific errors
This keeps getting asked on stackoverflow (just this morning : http://stackoverflow.com/a/39627892/390330) so thought there should be an issue to track it.
Ideation
Lots of linters do this:
- Ignore errors for regions (using inline comments
/** */). - Ignore errors per file (configured using tsconfig or command line)
- Ignore certain error codes (configured using tsconfig or command line)
There needs to be đ˛ đ here so have at it đš
More
- I had the desire for something like this just for JS file but that went away when we got
allowJs: https://github.com/Microsoft/TypeScript/issues/4094 â¤ď¸ - An issue for tracking JavaScript specific error customization : https://github.com/Microsoft/TypeScript/issues/6802
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 61
- Comments: 39 (20 by maintainers)
man⌠this is one of my all time favorite topics đ As I mentioned in https://github.com/Microsoft/TypeScript/issues/9448#issuecomment-229780542, https://github.com/Microsoft/TypeScript/issues/8855#issuecomment-223160647, https://github.com/Microsoft/TypeScript/issues/6771#issuecomment-178104716, https://github.com/Microsoft/TypeScript/issues/3691#issuecomment-168801858, and i am sure there is more, errors are not the problem, and suppressing them is not the solution; this analogues of switching off your fire alarm. The real problem is you have a faulty fire alarm. So instead of muffling the errors, I would like to know what is the specific error, and why you find it useless. then we can talk how we can make the experience better.
A couple of examples to go with my previous comment:
Here is a util function from bluebird:
It would be nice not to have to set
allowUnreachableCode: trueproject-wide just because of this one special case. That would cause a loss of safety in the rest of the project. What if we could preface just this function with// @allowUnreachableCode: true, thereby preserving unreachability checking everywhere else in the project?Here is part of a function from the TypeScript compiler:
Setting
noFallthroughCasesInSwitch: falseproject-wide would cause a loss of safety in the rest of the project. What if we could preface just this function with// @noFallthroughCasesInSwitch: false, thereby preserving fall-through checking everywhere else in the project?The reason, why we would need such of feature is very simple:
We have old applications, which we have to migrate step by step into a new framework. (An example would be migrating old JavaScript/TypeScript/⌠Codes from Angular1 to 2)
In the earlier steps we have to suppress some errors like
this[foo] = barand some other ones, so that the app is first runnable. If we can run the app in the new framework, we get the decision from Marketing/Management Department for the refactoring in depth. Marketing department is absolutely not interested in compiler errors.We have a pre-configured build system (big company) and may only change tsconfig.json. Currently the build sytem drums out our app because of existing errors. And there are a big amount of source codes and we have not the resources to correct every error in a short given time. Therefore we need some feature like to deactive certain errors, which were ok at that time (at the time of writing of that old stuff and the list is long.
As you see, there are certain use cases, that are not considered by the creators of TypeScript đ The world is not perfect and you may not always expect perfect pre-conditions. Therefore the ability to deactivate (be it very important) errors is an essential feature for the real world.
Thank you!
No matter how absurd it sounds:
yes, I want to disable the fire alarm and intentionally set on fire, because I have to test ( = management decision), how the people act, if there is fire, without fire alarm.
Another example, where I need to disable a rule per file.
React requires you to declare this object to use the Context feature, which is never used throughout the file. When NoUnusedLocals is turned on, this throws a compiler error because it is never directly used in the file.
@webia1 This is exactly my case. Iâm migrating a HUGE app from Backbone, even worse, keeping global scope and Backbone for a big(gerâŚ) part of the app still in place. Migrating part, checking if it works and then tightening type system and language - correctness is exactly my path I need to follow, as I have no spare year to refactor/rewrite the parts of legacy code (at the moment at leastâŚ). All the error messages about the errors I am aware anyway are actually noise blurring the real issues.
I do strongly support @basarat
Adam
@mhegazy, thatâs exactly it - for partially migrated projects, to use the stricter flags you have this workflow: (as you described)
Doesnât that seem like a broken workflow? If we had a way to disable specific errors for specific files, we wouldnât have to do the work around. For example, how about a triple-slash directive:
With some way to ignore specific errors for specific files, maybe the typescript code base could use
--noImplicitThisand--strictNullChecksâŚsure, until Anders adds some more CFA goodness that statically detects that as unreachable code.
I really appreciate the examples â these are what weâre looking for, to be sure! But Iâm going to break character here and state my strong subjective opinion about user code, which I usually try hard not to do: Both of those examples are horrifying.
Bluebird could just as easily use something like
!!false && eval(obj)to avoid that error. Or wrap the whole thing in a meaninglesstry / catch, which deopts to my knowledge. Anything they do here is just super-suspect anyway as there are no guarantees V8 wonât start doing smarter analysis and ignoring their unreachableeval. I would guess a hyper-low-level function like this (the 8-times loop to force a psuedoclass to be created⌠what?) occurs in extremely few libraries.Our own use of IFT here is awful â the second fall-through doesnât even save any LOC compared to just writing
break;at the// Fall-throughcomment! The first instance is somewhat more excusable but I would still prefer we just never do this.Again, my own opinion. I would like to see more examples and will try not to judge them so hard.
There are many TypeScript code generation tools that have issues with this as well. In some cases the code generation has to do quite a lot of effort in order to determine which parameters/locals are unused. This may not even be possible depending on which extension points are exposed, because the code generator may not have enough information to make this decision.
With TSLint this was never a problem because the code generator could include
/*tslint:disable*/at the top of generated files. Now that people are moving to the TypeScript rules the code generators have to try to enforce every rule that consumers might happen to use in their projects.Besides code generation, personally I was in the same position as @DomBlack and wanted to enable every strict rule because theyâre extremely useful. However I found myself toggling the rules on and off constantly while making commits so it wasnât worth the effort. Itâs just not worthwhile for existing (sizable) code bases to enable these rules unless the rules can be toggled per file.
While I agree with this in principle, in practice itâs difficult as the TSLint team is gradually removing linting rules as they get added to tsc - for example https://github.com/palantir/tslint/issues/661 deprecates no-unreachable and https://github.com/palantir/tslint/issues/1481 deprecates no-unused-variable.
I agree that ideally errors should be tuned and not ignored; that less than ideal code should be improved and not papered over; and that a dedicated linter should be used for maximum flexibility.
However, if the compiler is going to stray into the traditional territory of a linter, and especially where this encourages linters to remove rules, wouldnât it be pragmatic to add some small part of the flexibility a linter provides?
@rostacik đ đ It workâs like an Asprin, the headache is still existing, but you donât feel it anymore,âŚ
One philosophical distinction between errors of the like of noImplicitAny, can not find module, or type not assignable to, and ones reported by --allowUnreachableCode, --noFallthroughCasesInSwitch, and --noImplicitReturns, is that the later are more of linter functionality, that we are adding since âwe are already thereâ.
The compiler has done the control flow analysis, already so it might as well tell you you have an unreachable statement. these are not core to the type system, and are meant for the 90% case. if you want more customization for these you can switch them off entirely, and use a linter rule. linters already are built with exceptions for specific errors and different levels, etcâŚ
The other errors are really at the core of what the compiler does. for instance, if it does not know what shape a module has, it can not say anything about the imports, or how they are used, further use of these types would not be safe either, since an error type are just
any.,the tools can not guarantee that renamingxin one place will be safe, etc⌠at the core is the TypeScript value -proposition.Now, I am not saying all the errors that the compiler emit today are ideal. And this is why we should be having these discussions. and for instance, short-hand modules, and using of wild cards in module names were conceived because of users complaining about a too-stringent error message. if they were to switch that one off, they would have masked the real cause, and instead see a degradation of service in the compiler and the tools.