Support @ts-ignore for specific errors #19139
Comments
Seconding (and wanting to track this) This would be super helpful in our case as we have a class with a bunch of variables, and a function that accesses them by key value (vs direct getter function). As a result, they are never called directly within the class and are throwing the error despite being necessary to the functionality. I don't want to have to disable the "noUnusedLocals" check across the board, just in the two classes where this is the case. Edit - |
I would also love this, more specifically for the noUnusedLocals rule, we get errors on this:
Saying that BinaryExpression is not used, but it might be, depeding on the value of this.expression.type. I could make BinaryExpresison public, but I really think it is a private method. |
This would also be very useful for our team, we are slowly migrating a large JS app to TS. We'd like to turn on strict compilation flags (especially Specific error suppression would allow us to gradually migrate everything to strict compilation. |
It's actually absurd that this is even still an issue. I've experienced a problem related to this. The underlying cause was due to a typescript change in 2.4, as discussed here: We were then left with three options
option 1 is not preferable, as it means we can't leverage any new typescript features and can result in having mismatched dependencies options 2 and 3 are possible (although difficult), and they really only handle one such specific 'error' preventing successful compilation. Why is there not an option for us to 'ignore' TS2559 (as an example)? |
@Ristaaf I know it's been a while, but I think your use case ( |
Here's another little doozy that I don't believe is covered by any "normal" TS methods. Consider the following: You're dynamically creating a web worker, i.e. by using an const objectUrl = URL.createObjectURL(
new Blob(
[`(${
function() { ... }.toString()
})()`],
{ type: 'application/javascript' }
)
); ...and the body of that function contains the single most important thing a web worker can do, // inside worker function
setInterval(() => postMessage('from worker!'), 2000);
// ^^^ this causes TS error! 😿 Oh no! TypeScript's implementation of // inside worker function
setInterval(() => postMessage('from worker!', null), 2000);
// ^^^ this causes worker exception! ☠️ The web worker postMessage won't accept another parameter! Woe is me. Since it doesn't make sense to change the [correct] type definition for the window context's interface, and web workers can't use TypeScript [natively], it seems this would be a perfect opportunity to tell the TS compiler "Hey dude, that's a stringified version of some arbitrary Javascript that has nothing to do with you, your execution context even. Back off, get your own sandwich". |
@wosevision disclaimer: I never worked with Webworker till now. |
@HolgerJeromin Thanks, I appreciate the tip. I was aware of the TS webworker lib and target, but this situation is slightly different. The linchpin point is here:
...That is to say, the target is not a webworker. It's just regular browser JS that happens to be building the webworker. The lib should still reflect the regular lib.dom.d.ts because, for all intents and purposes, we are not inside a webworker and therefore lib.webworker.d.ts typings are useless everywhere else. It's such an edge case that it would feel silly to do anything other than ignore a line or two. |
Is there a reason this issue is still open? I depend on a library that has an incorrect documentation, and it causes unsilencable errors! See esteban-uo/picasa#27 for more info. This feels a bit silly. |
@jlengrand you could use a generic |
Ha nice, I didn't understand that! I saw the ts-ignore issue closed, thinking it had been dismissed. Thanks for the tip! |
Without fine control about how legacy files are handled it is really hard to introduce new typescript rules into a project. Please give this use case some more consideration. |
|
@RyanCavanaugh If I had hundreds of ts-ignores in my code, I'd definitely want them to have TScodes associated with them, to restrict their error-hiding radius. But in the few(?) cases where the.TScode kept changing, I might revert to a simple comment to avoid churn. The situation seems analogous to eslint, where users are already accustomed to updating their ignores as the error types subtly change. Are ts-ignores fundamentally different from eslint-ignores in this regard? |
This sounds largely like the need for a perfect solution is preventing a good solution. I can think of multiple responses to your specific argument, but I don't really want to get bogged down in arguing on one specific thing. Offhand, I've been through multiple migrations where they're much simpler this sort of one-off error squashing. Start with tooling to ignore the current errors so we can move forward writing new error-free code with the codes enabled. Is there a better path to enabling "strict" mode? Or say enabling new error codes in the future? |
Probably this feature isn't implemented because of TS team's test process. TS team frequently tests TypeScript using DefinitelyTyped and some projects but if @ts-ignore for specific errors is used in them, TS team has to maintain these @ts-ignore comments. TS team hates this maintenance cost. This would be why @ts-ignore for specific errors isn't implemented. FYI, I needs @ts-ignore for specific errors to ignore some language bugs in most cases: https://github.com/falsandtru/spica/search?q=ts-ignore&unscoped_q=ts-ignore A lot of bugs have still not been fixed. TypeScript hasn't provided any suitable solution to care these bugs. |
Would it be possible for the team to ignore ignore comments? |
@RyanCavanaugh I completely understand that there is no perfect solution (as @vpanta called it) but nevertheless I would very much prefer the option to only ignore specific errors. |
Today: "Why let perfect stand in the way of the good? Just do something right away, I'm sure it'll be fine" Tomorrow: "Yes, that new proposal would be more ideal, but we can't change the behavior now" / "Well why did you rush the feature instead of figuring it out first?" The day after: "Why is this language so full of inconsistencies? It's like the designers just rushed something out the door to satisfy people. Pretty disappointing that they weren't willing to take their time to do it right." |
@RyanCavanaugh I would agree with you on most design decisions but I think this is different because I don't think there is a "perfect" solution and silently ignoring possible errors does also not seem like the perfect solution. For this problem I would rather aim for a practical compromise. |
In all fairness, any decision made today or tomorrow wouldn't be "right away" considering this issue was opened in 2017...
Full? Are there really people here who sound like this? |
@RyanCavanaugh > there's a 1:1 relationship between error codes and messages. It seems to me like this is the source of our problems. Is this something that can be changed? |
Has anybody proposed solving Ryan's problem by maintaining a mapping of "deprecated" / "refined" / "OBE" error codes? (Remember folks, naming things is one of the Hard Problems. Sorry.) In his example, before TS7632 existed, the code would have been marked with TS2339. So, capture |
My proposal is that an error dictionary is created. All errors would have an immutable number and mutable description. Any change in an error description would never break anything. No need for extra maintenance. The text editor would be able to use this dictionary to show a tooltip with the current error description on hover and that is it. |
Ryan's example above isn't actually a change to an error, it's the introduction of a new, more detailed check that catches a subset of the errors that would previously have been caught. The critical thing is that the hypothetical TS7632 would not mean that TS2339 is completely obsolete. Consider type Foo = { x?: number; }
type Foo2 = { y?: string; }
const f: Foo = {};
f.y = "hey";
f.z = true; I assume Ryan is suggesting that, maybe in the future, the compiler will be smart enough to do string-similarity checks and give us a "did you mean?" style error. In that case, the That's why I suggested a mapping that captures this information. The new error message (TS7632) would have shown up as a more general message (TS2339) in a previous TS version, so knowing that means that |
@thw0rted My impression is: if a more recent TS version is really catching a new kind of error, that was previously no cought because of an oversight or language limitation, it should never be suppressed by old error codes being ignored. IMO that is the whole point of this feature rquest. Your example is not really a new error, it is an augumented way of dealing with an old error. I undersntand that, the way things work now, it would be required to use the new error code TS7632, thecnically making it a new error. But, this is not the true nature of this thing. Would it make sense to separate them into what is an error and what is a smart suggestion to solve this error? In that case, we would have preserved the original error TS2339, which is not in fact obsolete. And there would be a list of possible smart suggestions for each error code. |
@thw0rted I believe what you’re describing is what I proposed here, though I confess I haven’t followed this thread super closely of late. I think it addresses @RyanCavanaugh’s upgrade issue |
Pretty much, Ethan. Hah, I even thumbs-up'd the old post back in October! The only difference is that I was imagining storing the "parent" or "alt" information as a tree -- it could be thought of as "ancestry". I think this still makes the most sense. If all current errors are leaf nodes, then you can walk up to the root of the tree and each visited node is an error that the same line of code would have gotten under some previous version of the compiler. Storing it this way instead of as a flat array might be adding complexity for very little benefit, though. |
@RyanCavanaugh if I understand correctly, your main issue is with the fact that TS could give a different error code for an issue in the future causing upgrade pains? However every TS version is already assumed to be a breaking change, so why not give users the ability to choose how much the ignore radius should be? AFAIK the proposal is the following
New proposal Basically we're saying, let us decide how strict we want our ignore radius to be. In some projects, going yolo Every TS version upgrade is already a breaking change. There has been exactly 0 times, where a TS upgrade has just worked for me for our 100k+ lines codebase. So if you're fear is introducing more errors for a version upgrade, this hasn't been a big concern for us personally. Fixing @ts-expect-error issues with a new TS error code is a simple find replace. That's an easy class of errors to fix. I actually want to know when that happens and explicitly fix each one rather than it happening transparently. Also this issue is something I feel strongly about and would be happy to champion a PR if Typescript core members agree it's something they are willing to accept. |
This is something that would highly valuable to us. Having a |
@nojvek These things are all true qualitatively, but there is a quantitative aspect that needs consideration. We totally expect that most very large codebases will see a dozenish breaks during version migrations, and that the maintainers of those codebases look at the breaks and mostly say "Yeah I can see how that was sketchy".
The reason you haven't had this problem is precisely because we've avoided adding features (like this one) that would create that scenario. I don't know what more to say on that; not getting wet in a rainstorm is a bad reason to throw away one's umbrella. Here's a scenario that is entirely foreseeable:
You're acknowledging the danger of this feature, saying that you accept the danger, and therefore there's no problem with the feature existing. The problem is, we're not just adding the feature for you, we're adding it for everyone, and there's no way to put a EULA sticker on this that says "FYI, version to version upgrades are totally YOLO if you use this". They're going to see it on Stack Overflow, stick 40 different The downstream effects of "I accept the danger" thinking can already be seen with |
Proposal: Having an opt-in way to limit ts-expect-error radius by specifying exactly which error to ignore. If I understand correctly, the summary of your viewpoint is that TS team thinks that providing specific error code ignores is not a good future-proof solution. It should not be exposed to the user at all. Since it will regress the upgrade experience and TS team doesn't want to paint itself into a corner. That's a reasonable argument. Ultimately you are the guardians of TS so it's your call (even if some of us may disagree). I appreciate the explicit clarification. |
@RyanCavanaugh Then why have I admit the second example is a bit contrived; but for my first question, the documentation for ts-expect-error seems to be in direct conflict with the (good) points you were just making. I feel conflicted, because I agree with the points you're making, but agree with the points made in the 3.9 documentation, and would be valuable to our team. @RyanCavanaugh how would you respond to these excerpts:
Given this logic--that it's better to say
By adding a specific error code, instead of just blindly ignoring the line, the error can be PART of the test itself. In addition, many of the points that you bring up (that I agree with) are similar to the ones given in this article for picking
You're right that a danger of adding specific errors is that you will use it to squash random errors in a codebase (point 1). Another danger you point out is how this can be abused and bite people in the future when updating (point 2). From what I gather, having specific error codes amplifies the benefits listed in "Pick Just wondering what you think about this. Also, I'm not going to go through the initial |
Consider the fact that I don't see the same analogue here, because it's not at all obvious that error codes are not necessarily stable between versions. C# has to do a ton of backcompat engineering to make sure their warnings are consistent version-to-version and we don't want to do that (though people are already speculating about how we should implement it). If we add this feature, we are guaranteed going to stoke ire from engineers who go all-in on it without realizing this, and there's nothing I see that can prevent it. Maybe that future ire is worth it for the sake of whatever people are experiencing here, but frankly I have not seen the evidence for what kinds of problems people are encountering that this feature would solve better than other existing solutions. People just keep going in circles asking why it doesn't exist. I get that it feels bad to |
@RyanCavanaugh As a possible use case for this feature. I'm responsible for a pretty large (~100000 loc) project. During our incremental migration from JavaScript to TypeScript we had to use |
@RyanCavanaugh Very concisely written, and as someone that is only just thinking about this problem, you illustrated the history of these features in a way that really helped me understand where you're coming from. Thanks! |
@denissabramovs That's not very helpful. Check out the thread starting here for some rationale |
@RyanCavanaugh In my specific case I'm running into a problem related to immer losing symbol keys which I believe is caused by keyof removing well known symbols. For this case I have to use a ts-ignore statement. I think adding some compiler options would really help because ideally I want to remove these I think for I think the same approach where specific error Even if you don't opt into either of these behaviors you have the ability to periodically run a build with these rather than checking each line manually. |
Personally, I find entire TSC errors to be, without explicit rationale behind them, 100% useless. Oops, I broke at least 3 TS rules at once :) There are plenty of errors that are just that, errors, they should make someone stop and think about whether what they had just written was unsafe, and rewrite it, but the "errors" that I would like to disable en masse fall into a whole different category outside of safety and linting, into the area of "why is that an error in the first place?" |
For both TS18022 and TS18019, your linked issue points out that private methods only reached "Stage 3" quite recently and TS hasn't gotten around to supporting them yet. Likewise for other up-and-coming ES private features ( For TS2775, the linked issue (and a PR that is linked several times from there) make it pretty clear that there's a design limitation for control-flow analysis where you have to basically "re-type" the assert function when it's imported. (I agree with what appears to be the general consensus that the error message could be clearer, but at least searching for that error number brings you to those discussions.) This is irksome but not insurmountable. |
I think I'm experiencing a different error now that I look at it; I already know that reassigning an assertion function requires an explicit type, but what about direct calls? let azzert = new Assertion().assert;
azzert(foo); vs new Assertion().assert(foo); my particular case looked more like: class T {
static #assertIsT(x: unknown): asserts x is T { ... } // error
method(x: unknown) {
T.#assertIsT(x); // error
...
}
} but the real problem here is the lack of static private support and is the only reason that it can't be typed correctly.
Well... those issues have actually been open for quite some time, 10 and 11 months respectively. But, in reality, the numbers are a bit different:
An average of three years since they reached stage 3; these are bound to reach stage 4 soon. Also, there are errors like TS2376 and TS17009, which seem... like they fulfill the same role, why does one exist, if the other does? class T extends H {
foo = ...;
constructor() {
const x = bar();
super(x, x); // TS#### : "don't do that"
// do I do this? // super( bar(), bar() );
}
} |
I am not a Typescript expert, so I'll not add arguments of the previous debate. However, I would like to express the need of this granularity with an example. I use export type MyStackParamList = {
Index: undefined;
Show: {
id?: string;
};
Edit: {
id: string;
};
};
const Stack = createStackNavigator<RidesStackParamList>(); You may define multiple stacks like that, but I will not going to details here. Using the navigation.navigate('Payment'); Typescript will throw error However, this code part works like a charm. You can navigate to an another route of an another stack without issue Is it me wrongly using the library? Maybe, surely. It's classified. However, supposing it's an issue related to the vendor type definition, I can do anything waiting the fix than ignoring the error. But as @andy-ms said, I would like to be sure only this error will be silenced and avoid possible other mistakes on the same line. If specifying errors to ignore is dangerous according to some people here, what are the alternative for this case? Thanks for reading |
TypeScript Version: 2.6.0-dev.20171011
Code
Expected behavior:
Ability to make
ts-ignore
apply to the--noFallthroughCasesInSwitch
error but not to other errors.Actual behavior:
case "1":
would also compile.The text was updated successfully, but these errors were encountered: