Annotations and Assertions 12 exercises
explainer

The @ts-expect-error Directive in TypeScript

We've seen the @ts-expect-error directive throughout the challenges. It serves a similar purpose to @ts-ignore, but works in a slightly different way.

With @ts-expect-error, we tell TypeScript that we expect there to be an error on the next line of code.

For example, here's how we would use

Loading explainer

Transcript

00:00 We just covered TSignore, and now I want to cover TSExpectError, which is a slightly different version of TSignore, which does the same thing, and in fact you will have seen it throughout this course so far.

00:14 TSExpectError, if we look and we have the same handleFormData function as we had before, we're still getting the same error when we have e.target passed in, because e.target is supposed to be event target or null, and newFormData is expecting HTML form element.

00:29 Again, we can solve this with asAny, but we could also solve it with TSExpectError. Now what's going to happen here is on the next line, it's going to suppress all the errors. So still, we can do calls to fData and it will not error here.

00:46 It has exactly the same kind of destructive effect as TSignore, but the difference is that if this line of code stops erroring, so for instance, if I say, let's actually just move this out, and we'll say const string is of type number and we're assigning it ABC,

01:04 and I say TSExpectError, so the error, of course, goes away. Now if I actually just fix the error there, then TSExpectError is going to itself throw an error, because it's expecting an error to be there. So this is saying unused TSExpectError directive.

01:23 Essentially saying, I thought there was going to be an error on the next line, but there's not one. So a lot of people say TSExpectError, you should basically never ever use TSIgnore in your code base and you should use TSExpectError instead.

01:37 I don't think you should be using either of them in an application code base. TSExpectError, sure, it will give you an error if the error itself goes away. But TSExpectError, it doesn't let you expect a specific error. It doesn't let you say, you'll often see this actually in type testing.

01:56 This is the only way, and actually throughout this code base, let's see how many times I've used it, a bunch of different times. You'll often see, I'm going back to an early problem, TSExpectError string is not assignable to number. So this is checking if basically we call set range with something that isn't an array of numbers,

02:15 so a string inside here, then it's going to error. And this is actually erroring properly as we expect it to. But it's not actually, if we were to just say inside here, so set range or something like that, it's not going to actually tell us what is erroring.

02:33 It's just going to expect an error of some sort. So until that kind of demand is met by TypeScript itself, TSExpectError is really the only way of checking that something is erroring. But because of the same problems that you have with TSIgnore,

02:50 it's just too blunt an object to suppress errors. If you want to suppress this error properly, you should be using E.target as any. Because this means that there's an assignability error here that's going wrong.

03:05 E.target is not assignable to form data, even though all of our tests are passing. You can just say as any. Fantastic. And you'll still get all of the proper errors for if you misspell target or if you reference E incorrectly.

03:20 So TSExpectError, TSIgnore probably shouldn't be in your application codebases. You should be using as any instead. And even then, you should not be using as any very much.